mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 17:39:26 +02:00
separated springy balls from skeleton
This commit is contained in:
parent
1061b3eb4d
commit
4f49f1769e
4 changed files with 136 additions and 165 deletions
|
@ -98,12 +98,14 @@ Avatar::Avatar(Agent* owningAgent) :
|
||||||
}
|
}
|
||||||
|
|
||||||
_skeleton.initialize();
|
_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);
|
_avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS);
|
||||||
|
|
||||||
if (BALLS_ON) {
|
if (BALLS_ON) {
|
||||||
|
@ -113,6 +115,56 @@ Avatar::Avatar(Agent* owningAgent) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Avatar::initializeBalls() {
|
||||||
|
|
||||||
|
for (int b=0; b<NUM_AVATAR_JOINTS; b++) {
|
||||||
|
_ball[b].isCollidable = true;
|
||||||
|
_ball[b].position = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_ball[b].velocity = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_ball[b].radius = 0.0;
|
||||||
|
_ball[b].touchForce = 0.0;
|
||||||
|
_ball[b].jointTightness = BODY_SPRING_DEFAULT_TIGHTNESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// specify the radii of the joints
|
||||||
|
_ball[ AVATAR_JOINT_PELVIS ].radius = 0.07;
|
||||||
|
_ball[ AVATAR_JOINT_TORSO ].radius = 0.065;
|
||||||
|
_ball[ AVATAR_JOINT_CHEST ].radius = 0.08;
|
||||||
|
_ball[ AVATAR_JOINT_NECK_BASE ].radius = 0.03;
|
||||||
|
_ball[ AVATAR_JOINT_HEAD_BASE ].radius = 0.07;
|
||||||
|
|
||||||
|
_ball[ AVATAR_JOINT_LEFT_COLLAR ].radius = 0.04;
|
||||||
|
_ball[ AVATAR_JOINT_LEFT_SHOULDER ].radius = 0.03;
|
||||||
|
_ball[ AVATAR_JOINT_LEFT_ELBOW ].radius = 0.02;
|
||||||
|
_ball[ AVATAR_JOINT_LEFT_WRIST ].radius = 0.02;
|
||||||
|
_ball[ AVATAR_JOINT_LEFT_FINGERTIPS ].radius = 0.01;
|
||||||
|
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_COLLAR ].radius = 0.04;
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_SHOULDER ].radius = 0.03;
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_ELBOW ].radius = 0.02;
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_WRIST ].radius = 0.02;
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_FINGERTIPS ].radius = 0.01;
|
||||||
|
|
||||||
|
_ball[ AVATAR_JOINT_LEFT_HIP ].radius = 0.04;
|
||||||
|
_ball[ AVATAR_JOINT_LEFT_KNEE ].radius = 0.025;
|
||||||
|
_ball[ AVATAR_JOINT_LEFT_HEEL ].radius = 0.025;
|
||||||
|
_ball[ AVATAR_JOINT_LEFT_TOES ].radius = 0.025;
|
||||||
|
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_HIP ].radius = 0.04;
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_KNEE ].radius = 0.025;
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_HEEL ].radius = 0.025;
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_TOES ].radius = 0.025;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// to aid in hand-shaking and hand-holding, the right hand is not collidable
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_ELBOW ].isCollidable = false;
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_WRIST ].isCollidable = false;
|
||||||
|
_ball[ AVATAR_JOINT_RIGHT_FINGERTIPS].isCollidable = false;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Avatar::~Avatar() {
|
Avatar::~Avatar() {
|
||||||
_headData = NULL;
|
_headData = NULL;
|
||||||
delete _balls;
|
delete _balls;
|
||||||
|
@ -404,22 +456,22 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
right * _head.getLeanSideways() +
|
right * _head.getLeanSideways() +
|
||||||
front * _head.getLeanForward();
|
front * _head.getLeanForward();
|
||||||
|
|
||||||
_skeleton.joint[ AVATAR_JOINT_TORSO ].springyPosition += headLean * 0.1f;
|
_ball[ AVATAR_JOINT_TORSO ].position += headLean * 0.1f;
|
||||||
_skeleton.joint[ AVATAR_JOINT_CHEST ].springyPosition += headLean * 0.4f;
|
_ball[ AVATAR_JOINT_CHEST ].position += headLean * 0.4f;
|
||||||
_skeleton.joint[ AVATAR_JOINT_NECK_BASE ].springyPosition += headLean * 0.7f;
|
_ball[ AVATAR_JOINT_NECK_BASE ].position += headLean * 0.7f;
|
||||||
_skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition += headLean * 1.0f;
|
_ball[ AVATAR_JOINT_HEAD_BASE ].position += headLean * 1.0f;
|
||||||
|
|
||||||
_skeleton.joint[ AVATAR_JOINT_LEFT_COLLAR ].springyPosition += headLean * 0.6f;
|
_ball[ AVATAR_JOINT_LEFT_COLLAR ].position += headLean * 0.6f;
|
||||||
_skeleton.joint[ AVATAR_JOINT_LEFT_SHOULDER ].springyPosition += headLean * 0.6f;
|
_ball[ AVATAR_JOINT_LEFT_SHOULDER ].position += headLean * 0.6f;
|
||||||
_skeleton.joint[ AVATAR_JOINT_LEFT_ELBOW ].springyPosition += headLean * 0.2f;
|
_ball[ AVATAR_JOINT_LEFT_ELBOW ].position += headLean * 0.2f;
|
||||||
_skeleton.joint[ AVATAR_JOINT_LEFT_WRIST ].springyPosition += headLean * 0.1f;
|
_ball[ AVATAR_JOINT_LEFT_WRIST ].position += headLean * 0.1f;
|
||||||
_skeleton.joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].springyPosition += headLean * 0.0f;
|
_ball[ AVATAR_JOINT_LEFT_FINGERTIPS ].position += headLean * 0.0f;
|
||||||
|
|
||||||
_skeleton.joint[ AVATAR_JOINT_RIGHT_COLLAR ].springyPosition += headLean * 0.6f;
|
_ball[ AVATAR_JOINT_RIGHT_COLLAR ].position += headLean * 0.6f;
|
||||||
_skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].springyPosition += headLean * 0.6f;
|
_ball[ AVATAR_JOINT_RIGHT_SHOULDER ].position += headLean * 0.6f;
|
||||||
_skeleton.joint[ AVATAR_JOINT_RIGHT_ELBOW ].springyPosition += headLean * 0.2f;
|
_ball[ AVATAR_JOINT_RIGHT_ELBOW ].position += headLean * 0.2f;
|
||||||
_skeleton.joint[ AVATAR_JOINT_RIGHT_WRIST ].springyPosition += headLean * 0.1f;
|
_ball[ AVATAR_JOINT_RIGHT_WRIST ].position += headLean * 0.1f;
|
||||||
_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition += headLean * 0.0f;
|
_ball[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += headLean * 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,8 +485,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
|
_head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
|
||||||
_head.setPosition(_skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition);
|
_head.setPosition(_ball[ AVATAR_JOINT_HEAD_BASE ].position);
|
||||||
_head.setScale (_skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].radius);
|
_head.setScale (_ball[ AVATAR_JOINT_HEAD_BASE ].radius);
|
||||||
_head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]));
|
_head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]));
|
||||||
_head.simulate(deltaTime, !_owningAgent);
|
_head.simulate(deltaTime, !_owningAgent);
|
||||||
|
|
||||||
|
@ -450,15 +502,15 @@ void Avatar::checkForMouseRayTouching() {
|
||||||
|
|
||||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||||
|
|
||||||
glm::vec3 directionToBodySphere = glm::normalize(_skeleton.joint[b].springyPosition - _mouseRayOrigin);
|
glm::vec3 directionToBodySphere = glm::normalize(_ball[b].position - _mouseRayOrigin);
|
||||||
float dot = glm::dot(directionToBodySphere, _mouseRayDirection);
|
float dot = glm::dot(directionToBodySphere, _mouseRayDirection);
|
||||||
|
|
||||||
float range = _skeleton.joint[b].radius * JOINT_TOUCH_RANGE;
|
float range = _ball[b].radius * JOINT_TOUCH_RANGE;
|
||||||
|
|
||||||
if (dot > (1.0f - range)) {
|
if (dot > (1.0f - range)) {
|
||||||
_skeleton.joint[b].touchForce = (dot - (1.0f - range)) / range;
|
_ball[b].touchForce = (dot - (1.0f - range)) / range;
|
||||||
} else {
|
} 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.setHasInteractingOther(true);
|
||||||
_avatarTouch.setYourBodyPosition(_interactingOther->_position);
|
_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.setYourOrientation (_interactingOther->getOrientation());
|
||||||
_avatarTouch.setYourHandState (_interactingOther->_handState);
|
_avatarTouch.setYourHandState (_interactingOther->_handState);
|
||||||
|
|
||||||
|
@ -598,7 +650,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_avatarTouch.setMyHandState(_handState);
|
_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);
|
float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere);
|
||||||
if (distanceToBigSphere < myBodyApproximateBoundingRadius + radius) {
|
if (distanceToBigSphere < myBodyApproximateBoundingRadius + radius) {
|
||||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
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 distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter);
|
||||||
float combinedRadius = _skeleton.joint[b].radius + radius;
|
float combinedRadius = _ball[b].radius + radius;
|
||||||
|
|
||||||
if (distanceToBigSphereCenter < combinedRadius) {
|
if (distanceToBigSphereCenter < combinedRadius) {
|
||||||
jointCollision = true;
|
jointCollision = true;
|
||||||
|
@ -622,9 +674,9 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d
|
||||||
float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius);
|
float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius);
|
||||||
glm::vec3 collisionForce = vectorFromJointToBigSphereCenter * penetration;
|
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;
|
_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
|
// loop through the joints of each avatar to check for every possible collision
|
||||||
for (int b=1; b<NUM_AVATAR_JOINTS; b++) {
|
for (int b=1; b<NUM_AVATAR_JOINTS; b++) {
|
||||||
if (_skeleton.joint[b].isCollidable) {
|
if (_ball[b].isCollidable) {
|
||||||
|
|
||||||
for (int o=b+1; o<NUM_AVATAR_JOINTS; o++) {
|
for (int o=b+1; o<NUM_AVATAR_JOINTS; o++) {
|
||||||
if (otherAvatar->_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);
|
float distanceBetweenJoints = glm::length(vectorBetweenJoints);
|
||||||
|
|
||||||
if (distanceBetweenJoints > 0.0) { // to avoid divide by zero
|
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
|
// check for collision
|
||||||
if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) {
|
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;
|
glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * penetration * deltaTime;
|
||||||
bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime;
|
bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime;
|
||||||
|
|
||||||
_skeleton.joint[b].springyVelocity += ballPushForce;
|
_ball[b].velocity += ballPushForce;
|
||||||
otherAvatar->_skeleton.joint[o].springyVelocity -= ballPushForce;
|
otherAvatar->_ball[o].velocity -= ballPushForce;
|
||||||
|
|
||||||
}// check for collision
|
}// check for collision
|
||||||
} // to avoid divide by zero
|
} // to avoid divide by zero
|
||||||
|
@ -805,7 +857,7 @@ void Avatar::render(bool lookingInMirror) {
|
||||||
}
|
}
|
||||||
glPushMatrix();
|
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);
|
glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z);
|
||||||
glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation();
|
glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation();
|
||||||
glm::vec3 chatAxis = glm::axis(chatRotation);
|
glm::vec3 chatAxis = glm::axis(chatRotation);
|
||||||
|
@ -842,25 +894,25 @@ void Avatar::render(bool lookingInMirror) {
|
||||||
|
|
||||||
void Avatar::initializeBodySprings() {
|
void Avatar::initializeBodySprings() {
|
||||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||||
_skeleton.joint[b].springyPosition = _skeleton.joint[b].position;
|
_ball[b].position = _skeleton.joint[b].position;
|
||||||
_skeleton.joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
_ball[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::updateBodySprings(float deltaTime) {
|
void Avatar::updateBodySprings(float deltaTime) {
|
||||||
// Check for a large repositioning, and re-initialize body springs if this has happened
|
// Check for a large repositioning, and re-initialize body springs if this has happened
|
||||||
const float BEYOND_BODY_SPRING_RANGE = 2.f;
|
const float BEYOND_BODY_SPRING_RANGE = 2.f;
|
||||||
if (glm::length(_position - _skeleton.joint[AVATAR_JOINT_PELVIS].springyPosition) > BEYOND_BODY_SPRING_RANGE) {
|
if (glm::length(_position - _ball[AVATAR_JOINT_PELVIS].position) > BEYOND_BODY_SPRING_RANGE) {
|
||||||
_skeleton.initializeBodySprings();
|
initializeBodySprings();
|
||||||
}
|
}
|
||||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
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) {
|
if (_skeleton.joint[b].parent == AVATAR_JOINT_NULL) {
|
||||||
springVector -= _position;
|
springVector -= _position;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
springVector -= _skeleton.joint[ _skeleton.joint[b].parent ].springyPosition;
|
springVector -= _ball[ _skeleton.joint[b].parent ].position;
|
||||||
}
|
}
|
||||||
|
|
||||||
float length = glm::length(springVector);
|
float length = glm::length(springVector);
|
||||||
|
@ -869,23 +921,23 @@ void Avatar::updateBodySprings(float deltaTime) {
|
||||||
glm::vec3 springDirection = springVector / length;
|
glm::vec3 springDirection = springVector / length;
|
||||||
|
|
||||||
float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime;
|
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) {
|
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)
|
// 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
|
// apply decay
|
||||||
float decay = 1.0 - BODY_SPRING_DECAY * deltaTime;
|
float decay = 1.0 - BODY_SPRING_DECAY * deltaTime;
|
||||||
if (decay > 0.0) {
|
if (decay > 0.0) {
|
||||||
_skeleton.joint[b].springyVelocity *= decay;
|
_ball[b].velocity *= decay;
|
||||||
}
|
}
|
||||||
else {
|
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...
|
//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
|
if (_owningAgent || b == AVATAR_JOINT_RIGHT_ELBOW
|
||||||
|| b == AVATAR_JOINT_RIGHT_WRIST
|
|| b == AVATAR_JOINT_RIGHT_WRIST
|
||||||
|| b == AVATAR_JOINT_RIGHT_FINGERTIPS ) {
|
|| b == AVATAR_JOINT_RIGHT_FINGERTIPS ) {
|
||||||
glColor3f(SKIN_COLOR[0] + _skeleton.joint[b].touchForce * 0.3f,
|
glColor3f(SKIN_COLOR[0] + _ball[b].touchForce * 0.3f,
|
||||||
SKIN_COLOR[1] - _skeleton.joint[b].touchForce * 0.2f,
|
SKIN_COLOR[1] - _ball[b].touchForce * 0.2f,
|
||||||
SKIN_COLOR[2] - _skeleton.joint[b].touchForce * 0.1f);
|
SKIN_COLOR[2] - _ball[b].touchForce * 0.1f);
|
||||||
} else {
|
} else {
|
||||||
glColor4f(SKIN_COLOR[0] + _skeleton.joint[b].touchForce * 0.3f,
|
glColor4f(SKIN_COLOR[0] + _ball[b].touchForce * 0.3f,
|
||||||
SKIN_COLOR[1] - _skeleton.joint[b].touchForce * 0.2f,
|
SKIN_COLOR[1] - _ball[b].touchForce * 0.2f,
|
||||||
SKIN_COLOR[2] - _skeleton.joint[b].touchForce * 0.1f,
|
SKIN_COLOR[2] - _ball[b].touchForce * 0.1f,
|
||||||
alpha);
|
alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((b != AVATAR_JOINT_HEAD_TOP )
|
if ((b != AVATAR_JOINT_HEAD_TOP )
|
||||||
&& (b != AVATAR_JOINT_HEAD_BASE )) {
|
&& (b != AVATAR_JOINT_HEAD_BASE )) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(_skeleton.joint[b].springyPosition.x, _skeleton.joint[b].springyPosition.y, _skeleton.joint[b].springyPosition.z);
|
glTranslatef(_ball[b].position.x, _ball[b].position.y, _ball[b].position.z);
|
||||||
glutSolidSphere(_skeleton.joint[b].radius, 20.0f, 20.0f);
|
glutSolidSphere(_ball[b].radius, 20.0f, 20.0f);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1012,15 +1064,15 @@ void Avatar::renderBody(bool lookingInMirror) {
|
||||||
&& (b != AVATAR_JOINT_RIGHT_SHOULDER)) {
|
&& (b != AVATAR_JOINT_RIGHT_SHOULDER)) {
|
||||||
glColor3fv(DARK_SKIN_COLOR);
|
glColor3fv(DARK_SKIN_COLOR);
|
||||||
|
|
||||||
float r1 = _skeleton.joint[_skeleton.joint[b].parent ].radius * 0.8;
|
float r1 = _ball[_skeleton.joint[b].parent ].radius * 0.8;
|
||||||
float r2 = _skeleton.joint[b ].radius * 0.8;
|
float r2 = _ball[b ].radius * 0.8;
|
||||||
if (b == AVATAR_JOINT_HEAD_BASE) {
|
if (b == AVATAR_JOINT_HEAD_BASE) {
|
||||||
r1 *= 0.5f;
|
r1 *= 0.5f;
|
||||||
}
|
}
|
||||||
renderJointConnectingCone
|
renderJointConnectingCone
|
||||||
(
|
(
|
||||||
_skeleton.joint[_skeleton.joint[b].parent ].springyPosition,
|
_ball[_skeleton.joint[b].parent ].position,
|
||||||
_skeleton.joint[b ].springyPosition, r2, r2
|
_ball[b ].position, r2, r2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,8 +69,8 @@ public:
|
||||||
float getBodyYaw () const { return _bodyYaw;}
|
float getBodyYaw () const { return _bodyYaw;}
|
||||||
bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();}
|
bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();}
|
||||||
const glm::vec3& getHeadPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].position;}
|
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& getSpringyHeadPosition () const { return _ball[ AVATAR_JOINT_HEAD_BASE ].position;}
|
||||||
const glm::vec3& getJointPosition (AvatarJointID j) const { return _skeleton.joint[j].springyPosition;}
|
const glm::vec3& getJointPosition (AvatarJointID j) const { return _ball[j].position;}
|
||||||
|
|
||||||
glm::vec3 getBodyRightDirection () const { return getOrientation() * AVATAR_RIGHT; }
|
glm::vec3 getBodyRightDirection () const { return getOrientation() * AVATAR_RIGHT; }
|
||||||
glm::vec3 getBodyUpDirection () const { return getOrientation() * AVATAR_UP; }
|
glm::vec3 getBodyUpDirection () const { return getOrientation() * AVATAR_UP; }
|
||||||
|
@ -104,22 +104,15 @@ private:
|
||||||
Avatar(const Avatar&);
|
Avatar(const Avatar&);
|
||||||
Avatar& operator= (const Avatar&);
|
Avatar& operator= (const Avatar&);
|
||||||
|
|
||||||
/*
|
struct AvatarBall
|
||||||
struct AvatarJoint
|
|
||||||
{
|
{
|
||||||
AvatarJointID parent; // which joint is this joint connected to?
|
glm::vec3 position;
|
||||||
glm::vec3 position; // the position at the "end" of the joint - in global space
|
glm::vec3 velocity;
|
||||||
glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the "T-pose"
|
float jointTightness;
|
||||||
glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position)
|
float radius;
|
||||||
glm::vec3 springyVelocity; // used for special effects ( the velocity of the springy position)
|
bool isCollidable;
|
||||||
float springBodyTightness; // how tightly the springy position tries to stay on the position
|
float touchForce;
|
||||||
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)
|
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
|
|
||||||
Head _head;
|
Head _head;
|
||||||
Skeleton _skeleton;
|
Skeleton _skeleton;
|
||||||
|
@ -131,7 +124,7 @@ private:
|
||||||
float _bodyRollDelta;
|
float _bodyRollDelta;
|
||||||
glm::vec3 _movedHandOffset;
|
glm::vec3 _movedHandOffset;
|
||||||
glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion
|
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;
|
AvatarMode _mode;
|
||||||
glm::vec3 _cameraPosition;
|
glm::vec3 _cameraPosition;
|
||||||
glm::vec3 _handHoldingPosition;
|
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::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat)
|
||||||
glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const;
|
glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const;
|
||||||
void renderBody(bool lookingInMirror);
|
void renderBody(bool lookingInMirror);
|
||||||
void initializeSkeleton();
|
//void initializeSkeleton();
|
||||||
|
void initializeBalls();
|
||||||
void initializeBodySprings();
|
void initializeBodySprings();
|
||||||
void updateBodySprings( float deltaTime );
|
void updateBodySprings( float deltaTime );
|
||||||
void calculateBoneLengths();
|
void calculateBoneLengths();
|
||||||
|
|
|
@ -15,17 +15,11 @@ Skeleton::Skeleton() {
|
||||||
void Skeleton::initialize() {
|
void Skeleton::initialize() {
|
||||||
|
|
||||||
for (int b=0; b<NUM_AVATAR_JOINTS; b++) {
|
for (int b=0; b<NUM_AVATAR_JOINTS; b++) {
|
||||||
joint[b].isCollidable = true;
|
|
||||||
joint[b].parent = AVATAR_JOINT_NULL;
|
joint[b].parent = AVATAR_JOINT_NULL;
|
||||||
joint[b].position = glm::vec3(0.0, 0.0, 0.0);
|
joint[b].position = glm::vec3(0.0, 0.0, 0.0);
|
||||||
joint[b].defaultPosePosition = glm::vec3(0.0, 0.0, 0.0);
|
joint[b].defaultPosePosition = glm::vec3(0.0, 0.0, 0.0);
|
||||||
joint[b].springyPosition = glm::vec3(0.0, 0.0, 0.0);
|
|
||||||
joint[b].springyVelocity = glm::vec3(0.0, 0.0, 0.0);
|
|
||||||
joint[b].rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
|
joint[b].rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
joint[b].length = 0.0;
|
joint[b].length = 0.0;
|
||||||
joint[b].radius = 0.0;
|
|
||||||
joint[b].touchForce = 0.0;
|
|
||||||
joint[b].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// specify the parental hierarchy
|
// specify the parental hierarchy
|
||||||
|
@ -82,50 +76,14 @@ void Skeleton::initialize() {
|
||||||
joint[ AVATAR_JOINT_RIGHT_KNEE ].defaultPosePosition = glm::vec3( -0.01, -0.25, -0.03 );
|
joint[ AVATAR_JOINT_RIGHT_KNEE ].defaultPosePosition = glm::vec3( -0.01, -0.25, -0.03 );
|
||||||
joint[ AVATAR_JOINT_RIGHT_HEEL ].defaultPosePosition = glm::vec3( -0.01, -0.22, 0.08 );
|
joint[ AVATAR_JOINT_RIGHT_HEEL ].defaultPosePosition = glm::vec3( -0.01, -0.22, 0.08 );
|
||||||
joint[ AVATAR_JOINT_RIGHT_TOES ].defaultPosePosition = glm::vec3( 0.00, -0.03, -0.05 );
|
joint[ AVATAR_JOINT_RIGHT_TOES ].defaultPosePosition = glm::vec3( 0.00, -0.03, -0.05 );
|
||||||
|
|
||||||
// specify the radii of the joints
|
|
||||||
joint[ AVATAR_JOINT_PELVIS ].radius = 0.07;
|
|
||||||
joint[ AVATAR_JOINT_TORSO ].radius = 0.065;
|
|
||||||
joint[ AVATAR_JOINT_CHEST ].radius = 0.08;
|
|
||||||
joint[ AVATAR_JOINT_NECK_BASE ].radius = 0.03;
|
|
||||||
joint[ AVATAR_JOINT_HEAD_BASE ].radius = 0.07;
|
|
||||||
|
|
||||||
joint[ AVATAR_JOINT_LEFT_COLLAR ].radius = 0.04;
|
|
||||||
joint[ AVATAR_JOINT_LEFT_SHOULDER ].radius = 0.03;
|
|
||||||
joint[ AVATAR_JOINT_LEFT_ELBOW ].radius = 0.02;
|
|
||||||
joint[ AVATAR_JOINT_LEFT_WRIST ].radius = 0.02;
|
|
||||||
joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].radius = 0.01;
|
|
||||||
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_COLLAR ].radius = 0.04;
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_SHOULDER ].radius = 0.03;
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_ELBOW ].radius = 0.02;
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_WRIST ].radius = 0.02;
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].radius = 0.01;
|
|
||||||
|
|
||||||
joint[ AVATAR_JOINT_LEFT_HIP ].radius = 0.04;
|
|
||||||
joint[ AVATAR_JOINT_LEFT_KNEE ].radius = 0.025;
|
|
||||||
joint[ AVATAR_JOINT_LEFT_HEEL ].radius = 0.025;
|
|
||||||
joint[ AVATAR_JOINT_LEFT_TOES ].radius = 0.025;
|
|
||||||
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_HIP ].radius = 0.04;
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_KNEE ].radius = 0.025;
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_HEEL ].radius = 0.025;
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_TOES ].radius = 0.025;
|
|
||||||
|
|
||||||
/*
|
|
||||||
// to aid in hand-shaking and hand-holding, the right hand is not collidable
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_ELBOW ].isCollidable = false;
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_WRIST ].isCollidable = false;
|
|
||||||
joint[ AVATAR_JOINT_RIGHT_FINGERTIPS].isCollidable = false;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// calculate bone length
|
// calculate bone length
|
||||||
calculateBoneLengths();
|
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||||
|
joint[b].length = glm::length(joint[b].defaultPosePosition);
|
||||||
//set spring positions to be in the skeleton bone positions
|
}
|
||||||
initializeBodySprings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Skeleton::update(float deltaTime, const glm::quat& orientation, glm::vec3 position) {
|
void Skeleton::update(float deltaTime, const glm::quat& orientation, glm::vec3 position) {
|
||||||
|
|
||||||
// calculate positions of all bones by traversing the skeleton tree:
|
// calculate positions of all bones by traversing the skeleton tree:
|
||||||
|
@ -146,51 +104,30 @@ void Skeleton::update(float deltaTime, const glm::quat& orientation, glm::vec3 p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skeleton::initializeBodySprings() {
|
|
||||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
|
||||||
joint[b].springyPosition = joint[b].position;
|
|
||||||
joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Skeleton::calculateBoneLengths() {
|
|
||||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
|
||||||
joint[b].length = glm::length(joint[b].defaultPosePosition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float Skeleton::getArmLength() {
|
float Skeleton::getArmLength() {
|
||||||
|
|
||||||
return joint[ AVATAR_JOINT_RIGHT_ELBOW ].length
|
return joint[ AVATAR_JOINT_RIGHT_ELBOW ].length
|
||||||
+ joint[ AVATAR_JOINT_RIGHT_WRIST ].length
|
+ joint[ AVATAR_JOINT_RIGHT_WRIST ].length
|
||||||
+ joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].length;
|
+ joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Skeleton::getHeight() {
|
float Skeleton::getHeight() {
|
||||||
|
|
||||||
return
|
return
|
||||||
joint[ AVATAR_JOINT_LEFT_HEEL ].radius +
|
|
||||||
joint[ AVATAR_JOINT_LEFT_HEEL ].length +
|
joint[ AVATAR_JOINT_LEFT_HEEL ].length +
|
||||||
joint[ AVATAR_JOINT_LEFT_KNEE ].length +
|
joint[ AVATAR_JOINT_LEFT_KNEE ].length +
|
||||||
joint[ AVATAR_JOINT_PELVIS ].length +
|
joint[ AVATAR_JOINT_PELVIS ].length +
|
||||||
joint[ AVATAR_JOINT_TORSO ].length +
|
joint[ AVATAR_JOINT_TORSO ].length +
|
||||||
joint[ AVATAR_JOINT_CHEST ].length +
|
joint[ AVATAR_JOINT_CHEST ].length +
|
||||||
joint[ AVATAR_JOINT_NECK_BASE ].length +
|
joint[ AVATAR_JOINT_NECK_BASE ].length +
|
||||||
joint[ AVATAR_JOINT_HEAD_BASE ].length +
|
joint[ AVATAR_JOINT_HEAD_BASE ].length;
|
||||||
joint[ AVATAR_JOINT_HEAD_BASE ].radius;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float Skeleton::getPelvisStandingHeight() {
|
float Skeleton::getPelvisStandingHeight() {
|
||||||
|
return joint[ AVATAR_JOINT_LEFT_HEEL ].length +
|
||||||
return joint[ AVATAR_JOINT_LEFT_HEEL ].radius +
|
|
||||||
joint[ AVATAR_JOINT_LEFT_HEEL ].length +
|
|
||||||
joint[ AVATAR_JOINT_LEFT_KNEE ].length;
|
joint[ AVATAR_JOINT_LEFT_KNEE ].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Skeleton::getPelvisFloatingHeight() {
|
float Skeleton::getPelvisFloatingHeight() {
|
||||||
|
return joint[ AVATAR_JOINT_LEFT_HEEL ].length +
|
||||||
return joint[ AVATAR_JOINT_LEFT_HEEL ].radius +
|
|
||||||
joint[ AVATAR_JOINT_LEFT_HEEL ].length +
|
|
||||||
joint[ AVATAR_JOINT_LEFT_KNEE ].length +
|
joint[ AVATAR_JOINT_LEFT_KNEE ].length +
|
||||||
FLOATING_HEIGHT;
|
FLOATING_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@ public:
|
||||||
Skeleton();
|
Skeleton();
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
void initializeBodySprings();
|
|
||||||
void update(float deltaTime, const glm::quat&, glm::vec3 position);
|
void update(float deltaTime, const glm::quat&, glm::vec3 position);
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
|
@ -57,27 +56,16 @@ public:
|
||||||
float getPelvisStandingHeight();
|
float getPelvisStandingHeight();
|
||||||
float getPelvisFloatingHeight();
|
float getPelvisFloatingHeight();
|
||||||
|
|
||||||
struct AvatarJoint
|
struct AvatarJoint
|
||||||
{
|
{
|
||||||
AvatarJointID parent; // which joint is this joint connected to?
|
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 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 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; // the parent-relative rotation (orientation) of the joint as a quaternion
|
glm::quat rotation; // the parent-relative rotation (orientation) of the joint as a quaternion
|
||||||
float length; // the length of vector connecting the joint and its parent
|
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 ];
|
AvatarJoint joint[ NUM_AVATAR_JOINTS ];
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void calculateBoneLengths();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue