From 4f49f1769e5f2c70c734513ad4de1c9b6fcea112 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 31 May 2013 16:54:56 -0700 Subject: [PATCH] separated springy balls from skeleton --- interface/src/Avatar.cpp | 176 ++++++++++++++++++++++++------------- interface/src/Avatar.h | 30 +++---- interface/src/Skeleton.cpp | 79 ++--------------- interface/src/Skeleton.h | 16 +--- 4 files changed, 136 insertions(+), 165 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 080d9e31ca..61974dd9b1 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -98,12 +98,14 @@ Avatar::Avatar(Agent* owningAgent) : } _skeleton.initialize(); - - _height = _skeleton.getHeight(); - _maxArmLength = _skeleton.getArmLength(); - _pelvisStandingHeight = _skeleton.getPelvisStandingHeight(); - _pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight(); + initializeBalls(); + + _height = _skeleton.getHeight() + _ball[ AVATAR_JOINT_LEFT_HEEL ].radius + _ball[ AVATAR_JOINT_HEAD_BASE ].radius; + _maxArmLength = _skeleton.getArmLength(); + _pelvisStandingHeight = _skeleton.getPelvisStandingHeight() + _ball[ AVATAR_JOINT_LEFT_HEEL ].radius; + _pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight() + _ball[ AVATAR_JOINT_LEFT_HEEL ].radius; + _avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS); if (BALLS_ON) { @@ -113,6 +115,56 @@ Avatar::Avatar(Agent* owningAgent) : } } + +void Avatar::initializeBalls() { + + for (int b=0; b (1.0f - range)) { - _skeleton.joint[b].touchForce = (dot - (1.0f - range)) / range; + _ball[b].touchForce = (dot - (1.0f - range)) / range; } else { - _skeleton.joint[b].touchForce = 0.0; + _ball[b].touchForce = 0.0; } } } @@ -527,7 +579,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { _avatarTouch.setHasInteractingOther(true); _avatarTouch.setYourBodyPosition(_interactingOther->_position); - _avatarTouch.setYourHandPosition(_interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); + _avatarTouch.setYourHandPosition(_interactingOther->_ball[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); _avatarTouch.setYourOrientation (_interactingOther->getOrientation()); _avatarTouch.setYourHandState (_interactingOther->_handState); @@ -598,7 +650,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { } _avatarTouch.setMyHandState(_handState); - _avatarTouch.setMyHandPosition(_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); + _avatarTouch.setMyHandPosition(_ball[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); } } @@ -610,9 +662,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(_skeleton.joint[b].springyPosition - position); + glm::vec3 vectorFromJointToBigSphereCenter(_ball[b].position - position); float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter); - float combinedRadius = _skeleton.joint[b].radius + radius; + float combinedRadius = _ball[b].radius + radius; if (distanceToBigSphereCenter < combinedRadius) { jointCollision = true; @@ -622,9 +674,9 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius); glm::vec3 collisionForce = vectorFromJointToBigSphereCenter * penetration; - _skeleton.joint[b].springyVelocity += collisionForce * 0.0f * deltaTime; + _ball[b].velocity += collisionForce * 0.0f * deltaTime; _velocity += collisionForce * 40.0f * deltaTime; - _skeleton.joint[b].springyPosition = position + directionVector * combinedRadius; + _ball[b].position = position + directionVector * combinedRadius; } } } @@ -710,16 +762,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_skeleton.joint[o].isCollidable) { + if (otherAvatar->_ball[o].isCollidable) { - glm::vec3 vectorBetweenJoints(_skeleton.joint[b].springyPosition - otherAvatar->_skeleton.joint[o].springyPosition); + glm::vec3 vectorBetweenJoints(_ball[b].position - otherAvatar->_ball[o].position); float distanceBetweenJoints = glm::length(vectorBetweenJoints); if (distanceBetweenJoints > 0.0) { // to avoid divide by zero - float combinedRadius = _skeleton.joint[b].radius + otherAvatar->_skeleton.joint[o].radius; + float combinedRadius = _ball[b].radius + otherAvatar->_ball[o].radius; // check for collision if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) { @@ -731,8 +783,8 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * penetration * deltaTime; bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime; - _skeleton.joint[b].springyVelocity += ballPushForce; - otherAvatar->_skeleton.joint[o].springyVelocity -= ballPushForce; + _ball[b].velocity += ballPushForce; + otherAvatar->_ball[o].velocity -= ballPushForce; }// check for collision } // to avoid divide by zero @@ -805,7 +857,7 @@ void Avatar::render(bool lookingInMirror) { } glPushMatrix(); - glm::vec3 chatPosition = _skeleton.joint[AVATAR_JOINT_HEAD_BASE].springyPosition + getBodyUpDirection() * chatMessageHeight; + glm::vec3 chatPosition = _ball[AVATAR_JOINT_HEAD_BASE].position + getBodyUpDirection() * chatMessageHeight; glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z); glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation(); glm::vec3 chatAxis = glm::axis(chatRotation); @@ -842,25 +894,25 @@ void Avatar::render(bool lookingInMirror) { void Avatar::initializeBodySprings() { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - _skeleton.joint[b].springyPosition = _skeleton.joint[b].position; - _skeleton.joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + _ball[b].position = _skeleton.joint[b].position; + _ball[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f); } } void Avatar::updateBodySprings(float deltaTime) { // Check for a large repositioning, and re-initialize body springs if this has happened const float BEYOND_BODY_SPRING_RANGE = 2.f; - if (glm::length(_position - _skeleton.joint[AVATAR_JOINT_PELVIS].springyPosition) > BEYOND_BODY_SPRING_RANGE) { - _skeleton.initializeBodySprings(); + if (glm::length(_position - _ball[AVATAR_JOINT_PELVIS].position) > BEYOND_BODY_SPRING_RANGE) { + initializeBodySprings(); } for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - glm::vec3 springVector(_skeleton.joint[b].springyPosition); + glm::vec3 springVector(_ball[b].position); if (_skeleton.joint[b].parent == AVATAR_JOINT_NULL) { springVector -= _position; } else { - springVector -= _skeleton.joint[ _skeleton.joint[b].parent ].springyPosition; + springVector -= _ball[ _skeleton.joint[b].parent ].position; } float length = glm::length(springVector); @@ -869,23 +921,23 @@ void Avatar::updateBodySprings(float deltaTime) { glm::vec3 springDirection = springVector / length; float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime; - _skeleton.joint[b].springyVelocity -= springDirection * force; + _ball[b].velocity -= springDirection * force; if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) { - _skeleton.joint[_skeleton.joint[b].parent].springyVelocity += springDirection * force; + _ball[_skeleton.joint[b].parent].velocity += springDirection * force; } } // apply tightness force - (causing springy position to be close to rigid body position) - _skeleton.joint[b].springyVelocity += (_skeleton.joint[b].position - _skeleton.joint[b].springyPosition) * _skeleton.joint[b].springBodyTightness * deltaTime; + _ball[b].velocity += (_skeleton.joint[b].position - _ball[b].position) * _ball[b].jointTightness * deltaTime; // apply decay float decay = 1.0 - BODY_SPRING_DECAY * deltaTime; if (decay > 0.0) { - _skeleton.joint[b].springyVelocity *= decay; + _ball[b].velocity *= decay; } else { - _skeleton.joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + _ball[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f); } /* @@ -896,7 +948,7 @@ void Avatar::updateBodySprings(float deltaTime) { */ //update position by velocity... - _skeleton.joint[b].springyPosition += _skeleton.joint[b].springyVelocity * deltaTime; + _ball[b].position += _ball[b].velocity * deltaTime; } } @@ -981,21 +1033,21 @@ 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] + _skeleton.joint[b].touchForce * 0.3f, - SKIN_COLOR[1] - _skeleton.joint[b].touchForce * 0.2f, - SKIN_COLOR[2] - _skeleton.joint[b].touchForce * 0.1f); + glColor3f(SKIN_COLOR[0] + _ball[b].touchForce * 0.3f, + SKIN_COLOR[1] - _ball[b].touchForce * 0.2f, + SKIN_COLOR[2] - _ball[b].touchForce * 0.1f); } else { - 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, + glColor4f(SKIN_COLOR[0] + _ball[b].touchForce * 0.3f, + SKIN_COLOR[1] - _ball[b].touchForce * 0.2f, + SKIN_COLOR[2] - _ball[b].touchForce * 0.1f, alpha); } if ((b != AVATAR_JOINT_HEAD_TOP ) && (b != AVATAR_JOINT_HEAD_BASE )) { glPushMatrix(); - 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); + glTranslatef(_ball[b].position.x, _ball[b].position.y, _ball[b].position.z); + glutSolidSphere(_ball[b].radius, 20.0f, 20.0f); glPopMatrix(); } @@ -1012,15 +1064,15 @@ void Avatar::renderBody(bool lookingInMirror) { && (b != AVATAR_JOINT_RIGHT_SHOULDER)) { glColor3fv(DARK_SKIN_COLOR); - float r1 = _skeleton.joint[_skeleton.joint[b].parent ].radius * 0.8; - float r2 = _skeleton.joint[b ].radius * 0.8; + float r1 = _ball[_skeleton.joint[b].parent ].radius * 0.8; + float r2 = _ball[b ].radius * 0.8; if (b == AVATAR_JOINT_HEAD_BASE) { r1 *= 0.5f; } renderJointConnectingCone ( - _skeleton.joint[_skeleton.joint[b].parent ].springyPosition, - _skeleton.joint[b ].springyPosition, r2, r2 + _ball[_skeleton.joint[b].parent ].position, + _ball[b ].position, r2, r2 ); } } diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 5cc7d66f8b..462cb1bb12 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -69,8 +69,8 @@ public: float getBodyYaw () const { return _bodyYaw;} bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();} 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& getSpringyHeadPosition () const { return _ball[ AVATAR_JOINT_HEAD_BASE ].position;} + const glm::vec3& getJointPosition (AvatarJointID j) const { return _ball[j].position;} glm::vec3 getBodyRightDirection () const { return getOrientation() * AVATAR_RIGHT; } glm::vec3 getBodyUpDirection () const { return getOrientation() * AVATAR_UP; } @@ -104,22 +104,15 @@ private: Avatar(const Avatar&); Avatar& operator= (const Avatar&); -/* - struct AvatarJoint + struct AvatarBall { - 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 orientation; // this will eventually replace yaw, pitch and roll (and maybe orientation) - 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) + glm::vec3 position; + glm::vec3 velocity; + float jointTightness; + float radius; + bool isCollidable; + float touchForce; }; -*/ Head _head; Skeleton _skeleton; @@ -131,7 +124,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 ]; + AvatarBall _ball[ NUM_AVATAR_JOINTS ]; AvatarMode _mode; glm::vec3 _cameraPosition; glm::vec3 _handHoldingPosition; @@ -159,7 +152,8 @@ private: glm::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat) glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const; void renderBody(bool lookingInMirror); - void initializeSkeleton(); + //void initializeSkeleton(); + void initializeBalls(); void initializeBodySprings(); void updateBodySprings( float deltaTime ); void calculateBoneLengths(); diff --git a/interface/src/Skeleton.cpp b/interface/src/Skeleton.cpp index 78c40986af..97dded3254 100644 --- a/interface/src/Skeleton.cpp +++ b/interface/src/Skeleton.cpp @@ -15,17 +15,11 @@ Skeleton::Skeleton() { void Skeleton::initialize() { for (int b=0; b