mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 06:53:46 +02:00
more work on avatar touch
This commit is contained in:
parent
e96503de0d
commit
26bbb9917b
5 changed files with 185 additions and 84 deletions
|
@ -50,7 +50,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
const bool TESTING_AVATAR_TOUCH = false;
|
||||
const bool TESTING_AVATAR_TOUCH = true;
|
||||
|
||||
// Starfield information
|
||||
static char STAR_FILE[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt";
|
||||
|
|
|
@ -44,7 +44,7 @@ const float HEAD_MAX_YAW = 85;
|
|||
const float HEAD_MIN_YAW = -85;
|
||||
const float PERIPERSONAL_RADIUS = 1.0f;
|
||||
const float AVATAR_BRAKING_STRENGTH = 40.0f;
|
||||
const float JOINT_TOUCH_RANGE = 0.01f;
|
||||
const float MOUSE_RAY_TOUCH_RANGE = 0.01f;
|
||||
const float FLOATING_HEIGHT = 0.13f;
|
||||
const bool USING_HEAD_LEAN = false;
|
||||
const float LEAN_SENSITIVITY = 0.15;
|
||||
|
@ -64,7 +64,8 @@ float chatMessageHeight = 0.20;
|
|||
Avatar::Avatar(Agent* owningAgent) :
|
||||
AvatarData(owningAgent),
|
||||
_head(this),
|
||||
_TEST_bigSphereRadius(0.4f),
|
||||
_ballSpringsInitialized(false),
|
||||
_TEST_bigSphereRadius(0.5f),
|
||||
_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f),
|
||||
_mousePressed(false),
|
||||
_bodyPitchDelta(0.0f),
|
||||
|
@ -118,6 +119,8 @@ Avatar::Avatar(Agent* owningAgent) :
|
|||
|
||||
void Avatar::initializeBodyBalls() {
|
||||
|
||||
_ballSpringsInitialized = false; //this gets set to true on the first update pass...
|
||||
|
||||
for (int b=0; b<NUM_AVATAR_BODY_BALLS; b++) {
|
||||
_bodyBall[b].parentJoint = AVATAR_JOINT_NULL;
|
||||
_bodyBall[b].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
|
@ -129,61 +132,124 @@ void Avatar::initializeBodyBalls() {
|
|||
_bodyBall[b].jointTightness = BODY_SPRING_DEFAULT_TIGHTNESS;
|
||||
}
|
||||
|
||||
// specify the parent joint of each ball
|
||||
// specify the radius of each ball
|
||||
_bodyBall[ BODY_BALL_PELVIS ].radius = 0.07;
|
||||
_bodyBall[ BODY_BALL_TORSO ].radius = 0.065;
|
||||
_bodyBall[ BODY_BALL_CHEST ].radius = 0.08;
|
||||
_bodyBall[ BODY_BALL_NECK_BASE ].radius = 0.03;
|
||||
_bodyBall[ BODY_BALL_HEAD_BASE ].radius = 0.07;
|
||||
|
||||
_bodyBall[ BODY_BALL_LEFT_COLLAR ].radius = 0.04;
|
||||
_bodyBall[ BODY_BALL_LEFT_SHOULDER ].radius = 0.03;
|
||||
_bodyBall[ BODY_BALL_LEFT_ELBOW ].radius = 0.02;
|
||||
_bodyBall[ BODY_BALL_LEFT_WRIST ].radius = 0.02;
|
||||
_bodyBall[ BODY_BALL_LEFT_FINGERTIPS ].radius = 0.01;
|
||||
|
||||
_bodyBall[ BODY_BALL_RIGHT_COLLAR ].radius = 0.04;
|
||||
_bodyBall[ BODY_BALL_RIGHT_SHOULDER ].radius = 0.03;
|
||||
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].radius = 0.02;
|
||||
_bodyBall[ BODY_BALL_RIGHT_WRIST ].radius = 0.02;
|
||||
_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].radius = 0.01;
|
||||
|
||||
_bodyBall[ BODY_BALL_LEFT_HIP ].radius = 0.04;
|
||||
|
||||
//_bodyBall[ BODY_BALL_LEFT_MID_THIGH ].radius = 0.03;
|
||||
|
||||
_bodyBall[ BODY_BALL_LEFT_KNEE ].radius = 0.025;
|
||||
_bodyBall[ BODY_BALL_LEFT_HEEL ].radius = 0.025;
|
||||
_bodyBall[ BODY_BALL_LEFT_TOES ].radius = 0.025;
|
||||
|
||||
_bodyBall[ BODY_BALL_RIGHT_HIP ].radius = 0.04;
|
||||
_bodyBall[ BODY_BALL_RIGHT_KNEE ].radius = 0.025;
|
||||
_bodyBall[ BODY_BALL_RIGHT_HEEL ].radius = 0.025;
|
||||
_bodyBall[ BODY_BALL_RIGHT_TOES ].radius = 0.025;
|
||||
_bodyBall[ BODY_BALL_RIGHT_TOES ].radius = 0.025;
|
||||
|
||||
|
||||
// specify the parent joint for each ball
|
||||
_bodyBall[ BODY_BALL_PELVIS ].parentJoint = AVATAR_JOINT_NULL;
|
||||
_bodyBall[ BODY_BALL_TORSO ].parentJoint = AVATAR_JOINT_PELVIS;
|
||||
_bodyBall[ BODY_BALL_CHEST ].parentJoint = AVATAR_JOINT_TORSO;
|
||||
_bodyBall[ BODY_BALL_NECK_BASE ].parentJoint = AVATAR_JOINT_CHEST;
|
||||
_bodyBall[ BODY_BALL_HEAD_BASE ].parentJoint = AVATAR_JOINT_NECK_BASE;
|
||||
_bodyBall[ BODY_BALL_HEAD_TOP ].parentJoint = AVATAR_JOINT_HEAD_BASE;
|
||||
_bodyBall[ BODY_BALL_LEFT_COLLAR ].parentJoint = AVATAR_JOINT_CHEST;
|
||||
_bodyBall[ BODY_BALL_LEFT_SHOULDER ].parentJoint = AVATAR_JOINT_LEFT_COLLAR;
|
||||
_bodyBall[ BODY_BALL_LEFT_ELBOW ].parentJoint = AVATAR_JOINT_LEFT_SHOULDER;
|
||||
_bodyBall[ BODY_BALL_LEFT_WRIST ].parentJoint = AVATAR_JOINT_LEFT_ELBOW;
|
||||
_bodyBall[ BODY_BALL_LEFT_FINGERTIPS ].parentJoint = AVATAR_JOINT_LEFT_WRIST;
|
||||
_bodyBall[ BODY_BALL_RIGHT_COLLAR ].parentJoint = AVATAR_JOINT_CHEST;
|
||||
_bodyBall[ BODY_BALL_RIGHT_SHOULDER ].parentJoint = AVATAR_JOINT_RIGHT_COLLAR;
|
||||
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].parentJoint = AVATAR_JOINT_RIGHT_SHOULDER;
|
||||
_bodyBall[ BODY_BALL_RIGHT_WRIST ].parentJoint = AVATAR_JOINT_RIGHT_ELBOW;
|
||||
_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].parentJoint = AVATAR_JOINT_RIGHT_WRIST;
|
||||
_bodyBall[ BODY_BALL_LEFT_HIP ].parentJoint = AVATAR_JOINT_PELVIS;
|
||||
_bodyBall[ BODY_BALL_LEFT_KNEE ].parentJoint = AVATAR_JOINT_LEFT_HIP;
|
||||
_bodyBall[ BODY_BALL_LEFT_HEEL ].parentJoint = AVATAR_JOINT_LEFT_KNEE;
|
||||
_bodyBall[ BODY_BALL_LEFT_TOES ].parentJoint = AVATAR_JOINT_LEFT_HEEL;
|
||||
_bodyBall[ BODY_BALL_RIGHT_HIP ].parentJoint = AVATAR_JOINT_PELVIS;
|
||||
_bodyBall[ BODY_BALL_RIGHT_KNEE ].parentJoint = AVATAR_JOINT_RIGHT_HIP;
|
||||
_bodyBall[ BODY_BALL_RIGHT_HEEL ].parentJoint = AVATAR_JOINT_RIGHT_KNEE;
|
||||
_bodyBall[ BODY_BALL_RIGHT_TOES ].parentJoint = AVATAR_JOINT_RIGHT_HEEL;
|
||||
|
||||
_bodyBall[ BODY_BALL_PELVIS ].parentJoint = AVATAR_JOINT_PELVIS;
|
||||
_bodyBall[ BODY_BALL_TORSO ].parentJoint = AVATAR_JOINT_TORSO;
|
||||
_bodyBall[ BODY_BALL_CHEST ].parentJoint = AVATAR_JOINT_CHEST;
|
||||
_bodyBall[ BODY_BALL_NECK_BASE ].parentJoint = AVATAR_JOINT_NECK_BASE;
|
||||
_bodyBall[ BODY_BALL_HEAD_BASE ].parentJoint = AVATAR_JOINT_HEAD_BASE;
|
||||
_bodyBall[ BODY_BALL_HEAD_TOP ].parentJoint = AVATAR_JOINT_HEAD_TOP;
|
||||
_bodyBall[ BODY_BALL_LEFT_COLLAR ].parentJoint = AVATAR_JOINT_LEFT_COLLAR;
|
||||
_bodyBall[ BODY_BALL_LEFT_SHOULDER ].parentJoint = AVATAR_JOINT_LEFT_SHOULDER;
|
||||
_bodyBall[ BODY_BALL_LEFT_ELBOW ].parentJoint = AVATAR_JOINT_LEFT_ELBOW;
|
||||
_bodyBall[ BODY_BALL_LEFT_WRIST ].parentJoint = AVATAR_JOINT_LEFT_WRIST;
|
||||
_bodyBall[ BODY_BALL_LEFT_FINGERTIPS ].parentJoint = AVATAR_JOINT_LEFT_FINGERTIPS;
|
||||
_bodyBall[ BODY_BALL_RIGHT_COLLAR ].parentJoint = AVATAR_JOINT_RIGHT_COLLAR;
|
||||
_bodyBall[ BODY_BALL_RIGHT_SHOULDER ].parentJoint = AVATAR_JOINT_RIGHT_SHOULDER;
|
||||
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].parentJoint = AVATAR_JOINT_RIGHT_ELBOW;
|
||||
_bodyBall[ BODY_BALL_RIGHT_WRIST ].parentJoint = AVATAR_JOINT_RIGHT_WRIST;
|
||||
_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].parentJoint = AVATAR_JOINT_RIGHT_FINGERTIPS;
|
||||
_bodyBall[ BODY_BALL_LEFT_HIP ].parentJoint = AVATAR_JOINT_LEFT_HIP;
|
||||
_bodyBall[ BODY_BALL_LEFT_KNEE ].parentJoint = AVATAR_JOINT_LEFT_KNEE;
|
||||
_bodyBall[ BODY_BALL_LEFT_HEEL ].parentJoint = AVATAR_JOINT_LEFT_HEEL;
|
||||
_bodyBall[ BODY_BALL_LEFT_TOES ].parentJoint = AVATAR_JOINT_LEFT_TOES;
|
||||
_bodyBall[ BODY_BALL_RIGHT_HIP ].parentJoint = AVATAR_JOINT_RIGHT_HIP;
|
||||
_bodyBall[ BODY_BALL_RIGHT_KNEE ].parentJoint = AVATAR_JOINT_RIGHT_KNEE;
|
||||
_bodyBall[ BODY_BALL_RIGHT_HEEL ].parentJoint = AVATAR_JOINT_RIGHT_HEEL;
|
||||
_bodyBall[ BODY_BALL_RIGHT_TOES ].parentJoint = AVATAR_JOINT_RIGHT_TOES;
|
||||
|
||||
//_bodyBall[ BODY_BALL_LEFT_MID_THIGH].parentJoint = AVATAR_JOINT_LEFT_HIP;
|
||||
|
||||
// specify the parent offset for each ball
|
||||
_bodyBall[ BODY_BALL_PELVIS ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_TORSO ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_CHEST ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_NECK_BASE ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_HEAD_BASE ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_HEAD_TOP ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_LEFT_COLLAR ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_LEFT_SHOULDER ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_LEFT_ELBOW ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_LEFT_WRIST ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_LEFT_FINGERTIPS ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_RIGHT_COLLAR ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_RIGHT_SHOULDER ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_RIGHT_WRIST ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_LEFT_HIP ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_LEFT_KNEE ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_LEFT_HEEL ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_LEFT_TOES ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_RIGHT_HIP ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_RIGHT_KNEE ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_RIGHT_HEEL ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
_bodyBall[ BODY_BALL_RIGHT_TOES ].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
||||
|
||||
|
||||
//_bodyBall[ BODY_BALL_LEFT_MID_THIGH].parentOffset = glm::vec3(-0.1, -0.1, 0.0);
|
||||
|
||||
|
||||
// specify the parent BALL for each ball
|
||||
_bodyBall[ BODY_BALL_PELVIS ].parentBall = BODY_BALL_NULL;
|
||||
_bodyBall[ BODY_BALL_TORSO ].parentBall = BODY_BALL_PELVIS;
|
||||
_bodyBall[ BODY_BALL_CHEST ].parentBall = BODY_BALL_TORSO;
|
||||
_bodyBall[ BODY_BALL_NECK_BASE ].parentBall = BODY_BALL_CHEST;
|
||||
_bodyBall[ BODY_BALL_HEAD_BASE ].parentBall = BODY_BALL_NECK_BASE;
|
||||
_bodyBall[ BODY_BALL_HEAD_TOP ].parentBall = BODY_BALL_HEAD_BASE;
|
||||
_bodyBall[ BODY_BALL_LEFT_COLLAR ].parentBall = BODY_BALL_CHEST;
|
||||
_bodyBall[ BODY_BALL_LEFT_SHOULDER ].parentBall = BODY_BALL_LEFT_COLLAR;
|
||||
_bodyBall[ BODY_BALL_LEFT_ELBOW ].parentBall = BODY_BALL_LEFT_SHOULDER;
|
||||
_bodyBall[ BODY_BALL_LEFT_WRIST ].parentBall = BODY_BALL_LEFT_ELBOW;
|
||||
_bodyBall[ BODY_BALL_LEFT_FINGERTIPS ].parentBall = BODY_BALL_LEFT_WRIST;
|
||||
_bodyBall[ BODY_BALL_RIGHT_COLLAR ].parentBall = BODY_BALL_CHEST;
|
||||
_bodyBall[ BODY_BALL_RIGHT_SHOULDER ].parentBall = BODY_BALL_RIGHT_COLLAR;
|
||||
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].parentBall = BODY_BALL_RIGHT_SHOULDER;
|
||||
_bodyBall[ BODY_BALL_RIGHT_WRIST ].parentBall = BODY_BALL_RIGHT_ELBOW;
|
||||
_bodyBall[ BODY_BALL_RIGHT_FINGERTIPS ].parentBall = BODY_BALL_RIGHT_WRIST;
|
||||
_bodyBall[ BODY_BALL_LEFT_HIP ].parentBall = BODY_BALL_PELVIS;
|
||||
|
||||
//_bodyBall[ BODY_BALL_LEFT_MID_THIGH ].parentBall = BODY_BALL_LEFT_HIP;
|
||||
|
||||
// _bodyBall[ BODY_BALL_LEFT_KNEE ].parentBall = BODY_BALL_LEFT_MID_THIGH;
|
||||
_bodyBall[ BODY_BALL_LEFT_KNEE ].parentBall = BODY_BALL_LEFT_HIP;
|
||||
|
||||
_bodyBall[ BODY_BALL_LEFT_HEEL ].parentBall = BODY_BALL_LEFT_KNEE;
|
||||
_bodyBall[ BODY_BALL_LEFT_TOES ].parentBall = BODY_BALL_LEFT_HEEL;
|
||||
_bodyBall[ BODY_BALL_RIGHT_HIP ].parentBall = BODY_BALL_PELVIS;
|
||||
_bodyBall[ BODY_BALL_RIGHT_KNEE ].parentBall = BODY_BALL_RIGHT_HIP;
|
||||
_bodyBall[ BODY_BALL_RIGHT_HEEL ].parentBall = BODY_BALL_RIGHT_KNEE;
|
||||
_bodyBall[ BODY_BALL_RIGHT_TOES ].parentBall = BODY_BALL_RIGHT_HEEL;
|
||||
|
||||
/*
|
||||
// to aid in hand-shaking and hand-holding, the right hand is not collidable
|
||||
_bodyBall[ BODY_BALL_RIGHT_ELBOW ].isCollidable = false;
|
||||
|
@ -303,6 +369,25 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
// update avatar skeleton
|
||||
_skeleton.update(deltaTime, getOrientation(), _position);
|
||||
|
||||
//determine the lengths of the body springs now that we have updated the skeleton at least once
|
||||
if (!_ballSpringsInitialized) {
|
||||
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||
|
||||
glm::vec3 targetPosition
|
||||
= _skeleton.joint[_bodyBall[b].parentJoint].position
|
||||
+ _skeleton.joint[_bodyBall[b].parentJoint].rotation * _bodyBall[b].parentOffset;
|
||||
|
||||
glm::vec3 parentTargetPosition
|
||||
= _skeleton.joint[_bodyBall[b].parentJoint].position
|
||||
+ _skeleton.joint[_bodyBall[b].parentJoint].rotation * _bodyBall[b].parentOffset;
|
||||
|
||||
_bodyBall[b].springLength = glm::length(targetPosition - parentTargetPosition);
|
||||
}
|
||||
|
||||
_ballSpringsInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
// if this is not my avatar, then hand position comes from transmitted data
|
||||
if (_owningAgent) {
|
||||
_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition;
|
||||
|
@ -533,7 +618,7 @@ void Avatar::checkForMouseRayTouching() {
|
|||
glm::vec3 directionToBodySphere = glm::normalize(_bodyBall[b].position - _mouseRayOrigin);
|
||||
float dot = glm::dot(directionToBodySphere, _mouseRayDirection);
|
||||
|
||||
float range = _bodyBall[b].radius * JOINT_TOUCH_RANGE;
|
||||
float range = _bodyBall[b].radius * MOUSE_RAY_TOUCH_RANGE;
|
||||
|
||||
if (dot > (1.0f - range)) {
|
||||
_bodyBall[b].touchForce = (dot - (1.0f - range)) / range;
|
||||
|
@ -585,11 +670,6 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
|||
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
|
||||
|
||||
//Test: Show angle between your fwd vector and nearest avatar
|
||||
//glm::vec3 vectorBetweenUs = otherAvatar->getJointPosition(AVATAR_JOINT_PELVIS) -
|
||||
// getJointPosition(AVATAR_JOINT_PELVIS);
|
||||
//printLog("Angle between: %f\n", angleBetween(vectorBetweenUs, getBodyFrontDirection()));
|
||||
|
||||
// test whether shoulders are close enough to allow for reaching to touch hands
|
||||
glm::vec3 v(_position - otherAvatar->_position);
|
||||
float distance = glm::length(v);
|
||||
|
@ -689,16 +769,16 @@ 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_BODY_BALLS; b++) {
|
||||
glm::vec3 vectorFromJointToBigSphereCenter(_bodyBall[b].position - position);
|
||||
float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter);
|
||||
glm::vec3 vectorFromBallToBigSphereCenter(_bodyBall[b].position - position);
|
||||
float distanceToBigSphereCenter = glm::length(vectorFromBallToBigSphereCenter);
|
||||
float combinedRadius = _bodyBall[b].radius + radius;
|
||||
|
||||
if (distanceToBigSphereCenter < combinedRadius) {
|
||||
if (distanceToBigSphereCenter > 0.0) {
|
||||
glm::vec3 directionVector = vectorFromJointToBigSphereCenter / distanceToBigSphereCenter;
|
||||
glm::vec3 directionVector = vectorFromBallToBigSphereCenter / distanceToBigSphereCenter;
|
||||
|
||||
float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius);
|
||||
glm::vec3 collisionForce = vectorFromJointToBigSphereCenter * penetration;
|
||||
glm::vec3 collisionForce = vectorFromBallToBigSphereCenter * penetration;
|
||||
|
||||
_velocity += collisionForce * 40.0f * deltaTime;
|
||||
_bodyBall[b].position = position + directionVector * combinedRadius;
|
||||
|
@ -792,18 +872,18 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime
|
|||
for (int o=b+1; o<NUM_AVATAR_BODY_BALLS; o++) {
|
||||
if (otherAvatar->_bodyBall[o].isCollidable) {
|
||||
|
||||
glm::vec3 vectorBetweenJoints(_bodyBall[b].position - otherAvatar->_bodyBall[o].position);
|
||||
float distanceBetweenJoints = glm::length(vectorBetweenJoints);
|
||||
glm::vec3 vectorBetweenBalls(_bodyBall[b].position - otherAvatar->_bodyBall[o].position);
|
||||
float distanceBetweenBalls = glm::length(vectorBetweenBalls);
|
||||
|
||||
if (distanceBetweenJoints > 0.0) { // to avoid divide by zero
|
||||
if (distanceBetweenBalls > 0.0) { // to avoid divide by zero
|
||||
float combinedRadius = _bodyBall[b].radius + otherAvatar->_bodyBall[o].radius;
|
||||
|
||||
// check for collision
|
||||
if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) {
|
||||
glm::vec3 directionVector = vectorBetweenJoints / distanceBetweenJoints;
|
||||
if (distanceBetweenBalls < combinedRadius * COLLISION_RADIUS_SCALAR) {
|
||||
glm::vec3 directionVector = vectorBetweenBalls / distanceBetweenBalls;
|
||||
|
||||
// push balls away from each other and apply friction
|
||||
float penetration = 1.0f - (distanceBetweenJoints / (combinedRadius * COLLISION_RADIUS_SCALAR));
|
||||
float penetration = 1.0f - (distanceBetweenBalls / (combinedRadius * COLLISION_RADIUS_SCALAR));
|
||||
|
||||
glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * penetration * deltaTime;
|
||||
bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime;
|
||||
|
@ -919,7 +999,12 @@ void Avatar::render(bool lookingInMirror) {
|
|||
|
||||
void Avatar::resetBodyBalls() {
|
||||
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||
_bodyBall[b].position = _skeleton.joint[b].position; // put balls on joints
|
||||
|
||||
glm::vec3 targetPosition
|
||||
= _skeleton.joint[_bodyBall[b].parentJoint].position
|
||||
+ _skeleton.joint[_bodyBall[b].parentJoint].rotation * _bodyBall[b].parentOffset;
|
||||
|
||||
_bodyBall[b].position = targetPosition; // put ball on target position
|
||||
_bodyBall[b].velocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
@ -931,30 +1016,39 @@ void Avatar::updateBodyBalls(float deltaTime) {
|
|||
resetBodyBalls();
|
||||
}
|
||||
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||
glm::vec3 springVector(_bodyBall[b].position);
|
||||
|
||||
if (b == BODY_BALL_PELVIS) {
|
||||
springVector -= _position;
|
||||
}
|
||||
else {
|
||||
springVector -= _bodyBall[ _skeleton.joint[b].parent ].position;
|
||||
}
|
||||
|
||||
float length = glm::length(springVector);
|
||||
|
||||
if (length > 0.0f) { // to avoid divide by zero
|
||||
glm::vec3 springDirection = springVector / length;
|
||||
|
||||
float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime;
|
||||
_bodyBall[b].velocity -= springDirection * force;
|
||||
|
||||
if (_ballSpringsInitialized) {
|
||||
|
||||
//apply spring forces
|
||||
glm::vec3 springVector(_bodyBall[b].position);
|
||||
|
||||
if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) {
|
||||
_bodyBall[_skeleton.joint[b].parent].velocity += springDirection * force;
|
||||
if (b == BODY_BALL_PELVIS) {
|
||||
springVector -= _position;
|
||||
}
|
||||
else {
|
||||
springVector -= _bodyBall[_bodyBall[b].parentBall].position;
|
||||
}
|
||||
|
||||
float length = glm::length(springVector);
|
||||
|
||||
if (length > 0.0f) { // to avoid divide by zero
|
||||
glm::vec3 springDirection = springVector / length;
|
||||
|
||||
float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime;
|
||||
_bodyBall[b].velocity -= springDirection * force;
|
||||
|
||||
if (_bodyBall[b].parentBall != BODY_BALL_NULL) {
|
||||
_bodyBall[_bodyBall[b].parentBall].velocity += springDirection * force;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply tightness force - (causing ball position to be close to skeleton joint position)
|
||||
_bodyBall[b].velocity += (_skeleton.joint[b].position - _bodyBall[b].position) * _bodyBall[b].jointTightness * deltaTime;
|
||||
glm::vec3 targetPosition
|
||||
= _skeleton.joint[_bodyBall[b].parentJoint].position
|
||||
+ _skeleton.joint[_bodyBall[b].parentJoint].rotation * _bodyBall[b].parentOffset;
|
||||
|
||||
_bodyBall[b].velocity += (targetPosition - _bodyBall[b].position) * _bodyBall[b].jointTightness * deltaTime;
|
||||
|
||||
// apply decay
|
||||
float decay = 1.0 - BODY_SPRING_DECAY * deltaTime;
|
||||
|
@ -1077,7 +1171,7 @@ void Avatar::renderBody(bool lookingInMirror) {
|
|||
}
|
||||
|
||||
// Render the cone connecting this ball to its parent
|
||||
if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) {
|
||||
if (_bodyBall[b].parentBall != BODY_BALL_NULL) {
|
||||
if ((b != BODY_BALL_HEAD_TOP )
|
||||
&& (b != BODY_BALL_HEAD_BASE )
|
||||
&& (b != BODY_BALL_PELVIS )
|
||||
|
@ -1089,15 +1183,15 @@ void Avatar::renderBody(bool lookingInMirror) {
|
|||
&& (b != BODY_BALL_RIGHT_SHOULDER)) {
|
||||
glColor3fv(DARK_SKIN_COLOR);
|
||||
|
||||
float r1 = _bodyBall[_skeleton.joint[b].parent ].radius * 0.8;
|
||||
float r2 = _bodyBall[b ].radius * 0.8;
|
||||
float r1 = _bodyBall[_bodyBall[b].parentBall ].radius * 0.8;
|
||||
float r2 = _bodyBall[b].radius * 0.8;
|
||||
if (b == BODY_BALL_HEAD_BASE) {
|
||||
r1 *= 0.5f;
|
||||
}
|
||||
renderJointConnectingCone
|
||||
(
|
||||
_bodyBall[_skeleton.joint[b].parent ].position,
|
||||
_bodyBall[b ].position, r2, r2
|
||||
_bodyBall[_bodyBall[b].parentBall].position,
|
||||
_bodyBall[b].position, r2, r2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ enum AvatarBodyBallID
|
|||
BODY_BALL_RIGHT_KNEE,
|
||||
BODY_BALL_RIGHT_HEEL,
|
||||
BODY_BALL_RIGHT_TOES,
|
||||
|
||||
//TEST!
|
||||
//BODY_BALL_LEFT_MID_THIGH,
|
||||
NUM_AVATAR_BODY_BALLS
|
||||
};
|
||||
|
||||
|
@ -132,18 +135,21 @@ private:
|
|||
|
||||
struct AvatarBall
|
||||
{
|
||||
AvatarJointID parentJoint;
|
||||
glm::vec3 parentOffset;
|
||||
glm::vec3 position;
|
||||
glm::vec3 velocity;
|
||||
float jointTightness;
|
||||
float radius;
|
||||
bool isCollidable;
|
||||
float touchForce;
|
||||
AvatarJointID parentJoint; // the skeletal joint that serves as a reference for determining the position
|
||||
glm::vec3 parentOffset; // a 3D vector in the frame of reference of the parent skeletal joint
|
||||
AvatarBodyBallID parentBall; // the ball to which this ball is constrained for spring forces
|
||||
glm::vec3 position; // the actual dynamic position of the ball at any given time
|
||||
glm::vec3 velocity; // the velocity of the ball
|
||||
float springLength; // the ideal length of the spring between this ball and its parentBall
|
||||
float jointTightness; // how tightly the ball position attempts to stay at its ideal position (determined by parentOffset)
|
||||
float radius; // the radius of the ball
|
||||
bool isCollidable; // whether or not the ball responds to collisions
|
||||
float touchForce; // a scalar determining the amount that the cursor (or hand) is penetrating the ball
|
||||
};
|
||||
|
||||
Head _head;
|
||||
Skeleton _skeleton;
|
||||
bool _ballSpringsInitialized;
|
||||
float _TEST_bigSphereRadius;
|
||||
glm::vec3 _TEST_bigSpherePosition;
|
||||
bool _mousePressed;
|
||||
|
@ -151,7 +157,6 @@ private:
|
|||
float _bodyYawDelta;
|
||||
float _bodyRollDelta;
|
||||
glm::vec3 _movedHandOffset;
|
||||
glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion
|
||||
AvatarBall _bodyBall[ NUM_AVATAR_BODY_BALLS ];
|
||||
AvatarMode _mode;
|
||||
glm::vec3 _cameraPosition;
|
||||
|
|
|
@ -101,6 +101,7 @@ void Skeleton::update(float deltaTime, const glm::quat& orientation, glm::vec3 p
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
float Skeleton::getArmLength() {
|
||||
return joint[ AVATAR_JOINT_RIGHT_ELBOW ].length
|
||||
+ joint[ AVATAR_JOINT_RIGHT_WRIST ].length
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
float getHeight();
|
||||
float getPelvisStandingHeight();
|
||||
float getPelvisFloatingHeight();
|
||||
//glm::vec3 getJointVectorFromParent(AvatarJointID jointID) {return joint[jointID].position - joint[joint[jointID].parent].position; }
|
||||
|
||||
struct AvatarJoint
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue