mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 18:23:54 +02:00
improved collisions between avatars
This commit is contained in:
parent
308b9dcf82
commit
5c3bd5fe87
4 changed files with 72 additions and 53 deletions
|
@ -121,7 +121,7 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
// put her hand out so somebody can shake it
|
||||
eve.setHandPosition(glm::vec3(eve.getPosition()[0] - 0.2,
|
||||
0.25,
|
||||
0.32, // this is the same as the pelvis standing height (as of 4/26/13)
|
||||
eve.getPosition()[2] + 0.1));
|
||||
// read eve's audio data
|
||||
AudioInjector eveAudioInjector("eve.raw");
|
||||
|
|
|
@ -328,11 +328,7 @@ void Avatar::simulate(float deltaTime) {
|
|||
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
|
||||
|
||||
// check for collisions with other avatars and respond
|
||||
updateAvatarCollisionDetectionAndResponse(otherAvatar->getPosition(),
|
||||
0.1,
|
||||
0.1,
|
||||
otherAvatar->getBodyUpDirection(),
|
||||
deltaTime);
|
||||
updateCollisionWithOtherAvatar(otherAvatar, deltaTime );
|
||||
|
||||
// test other avatar hand position for proximity
|
||||
glm::vec3 v( _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position );
|
||||
|
@ -381,12 +377,8 @@ void Avatar::simulate(float deltaTime) {
|
|||
}
|
||||
|
||||
if (usingBigSphereCollisionTest) {
|
||||
// test for avatar collision response (using a big sphere :)
|
||||
updateAvatarCollisionDetectionAndResponse(_TEST_bigSpherePosition,
|
||||
_TEST_bigSphereRadius,
|
||||
_TEST_bigSphereRadius,
|
||||
glm::vec3( 0.0, 1.0, 0.0 ),
|
||||
deltaTime);
|
||||
// test for avatar collision response with the big sphere
|
||||
updateCollisionWithSphere( _TEST_bigSpherePosition, _TEST_bigSphereRadius, deltaTime );
|
||||
}
|
||||
|
||||
if ( AVATAR_GRAVITY ) {
|
||||
|
@ -540,31 +532,22 @@ void Avatar::simulate(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
float Avatar::getGirth() {
|
||||
return COLLISION_BODY_RADIUS;
|
||||
}
|
||||
|
||||
float Avatar::getHeight() {
|
||||
return COLLISION_HEIGHT;
|
||||
return _height;
|
||||
}
|
||||
|
||||
// This is a workspace for testing avatar body collision detection and response
|
||||
void Avatar::updateAvatarCollisionDetectionAndResponse(glm::vec3 collisionPosition,
|
||||
float collisionGirth,
|
||||
float collisionHeight,
|
||||
glm::vec3 collisionUpVector,
|
||||
float deltaTime) {
|
||||
|
||||
|
||||
void Avatar::updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime ) {
|
||||
float myBodyApproximateBoundingRadius = 1.0f;
|
||||
glm::vec3 vectorFromMyBodyToBigSphere(_position - collisionPosition);
|
||||
glm::vec3 vectorFromMyBodyToBigSphere(_position - position);
|
||||
bool jointCollision = false;
|
||||
|
||||
float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere);
|
||||
if ( distanceToBigSphere < myBodyApproximateBoundingRadius + collisionGirth ) {
|
||||
if ( distanceToBigSphere < myBodyApproximateBoundingRadius + radius ) {
|
||||
for (int b = 0; b < NUM_AVATAR_BONES; b++) {
|
||||
glm::vec3 vectorFromJointToBigSphereCenter(_bone[b].springyPosition - collisionPosition);
|
||||
glm::vec3 vectorFromJointToBigSphereCenter(_bone[b].springyPosition - position);
|
||||
float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter);
|
||||
float combinedRadius = _bone[b].radius + collisionGirth;
|
||||
float combinedRadius = _bone[b].radius + radius;
|
||||
|
||||
if ( distanceToBigSphereCenter < combinedRadius ) {
|
||||
jointCollision = true;
|
||||
|
@ -576,7 +559,7 @@ void Avatar::updateAvatarCollisionDetectionAndResponse(glm::vec3 collisionPositi
|
|||
|
||||
_bone[b].springyVelocity += collisionForce * 30.0f * deltaTime;
|
||||
_velocity += collisionForce * 100.0f * deltaTime;
|
||||
_bone[b].springyPosition = collisionPosition + directionVector * combinedRadius;
|
||||
_bone[b].springyPosition = position + directionVector * combinedRadius;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -590,6 +573,38 @@ void Avatar::updateAvatarCollisionDetectionAndResponse(glm::vec3 collisionPositi
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Avatar::updateCollisionWithOtherAvatar( Avatar * otherAvatar, float deltaTime ) {
|
||||
|
||||
glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position);
|
||||
|
||||
if ( glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF ) {
|
||||
|
||||
for (int b=1; b<NUM_AVATAR_BONES; b++) {
|
||||
for (int o=b+1; o<NUM_AVATAR_BONES; o++) {
|
||||
|
||||
glm::vec3 vectorBetweenJoints(_bone[b].springyPosition - otherAvatar->_bone[o].springyPosition);
|
||||
float distanceBetweenJoints = glm::length(vectorBetweenJoints);
|
||||
|
||||
if ( distanceBetweenJoints > 0.0 ) {
|
||||
float combinedRadius = _bone[b].radius + otherAvatar->_bone[o].radius;
|
||||
|
||||
if ( distanceBetweenJoints < combinedRadius * 1.8) {
|
||||
glm::vec3 directionVector = vectorBetweenJoints / distanceBetweenJoints;
|
||||
|
||||
_bone[b].springyVelocity += directionVector * 0.1f * deltaTime;
|
||||
_velocity += directionVector * 3.0f * deltaTime;
|
||||
|
||||
float momentum = 1.0 - COLLISION_FRICTION * deltaTime;
|
||||
if ( momentum < 0.0 ) { momentum = 0.0;}
|
||||
_velocity *= momentum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Avatar::setDisplayingHead( bool displayingHead ) {
|
||||
_displayingHead = displayingHead;
|
||||
}
|
||||
|
@ -965,12 +980,22 @@ void Avatar::initializeSkeleton() {
|
|||
calculateBoneLengths();
|
||||
|
||||
_pelvisStandingHeight =
|
||||
_bone[ AVATAR_BONE_PELVIS_SPINE ].length +
|
||||
_bone[ AVATAR_BONE_LEFT_THIGH ].length +
|
||||
_bone[ AVATAR_BONE_LEFT_FOOT ].radius +
|
||||
_bone[ AVATAR_BONE_LEFT_SHIN ].length +
|
||||
_bone[ AVATAR_BONE_LEFT_FOOT ].length +
|
||||
_bone[ AVATAR_BONE_RIGHT_FOOT ].radius;
|
||||
|
||||
_bone[ AVATAR_BONE_LEFT_THIGH ].length +
|
||||
_bone[ AVATAR_BONE_PELVIS_SPINE ].length;
|
||||
//printf( "_pelvisStandingHeight = %f\n", _pelvisStandingHeight );
|
||||
|
||||
_height =
|
||||
(
|
||||
_pelvisStandingHeight +
|
||||
_bone[ AVATAR_BONE_MID_SPINE ].length +
|
||||
_bone[ AVATAR_BONE_CHEST_SPINE].length +
|
||||
_bone[ AVATAR_BONE_NECK ].length +
|
||||
_bone[ AVATAR_BONE_HEAD ].length +
|
||||
_bone[ AVATAR_BONE_HEAD ].radius
|
||||
);
|
||||
|
||||
// generate world positions
|
||||
updateSkeleton();
|
||||
}
|
||||
|
|
|
@ -32,8 +32,7 @@ const float YAW_MAG = 500.0; //JJV - changed from 300.0;
|
|||
const float TEST_YAW_DECAY = 5.0;
|
||||
const float LIN_VEL_DECAY = 5.0;
|
||||
|
||||
const float COLLISION_BODY_RADIUS = 0.1;
|
||||
const float COLLISION_HEIGHT = 1.5;
|
||||
const float COLLISION_FRICTION = 0.5;
|
||||
|
||||
enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
|
||||
|
||||
|
@ -103,7 +102,7 @@ struct AvatarBone
|
|||
glm::vec3 position; // the position at the "end" of the bone
|
||||
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::dvec3 springyVelocity; // used for special effects ( the velocity of the springy 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 bone rotation off the parent
|
||||
|
@ -255,25 +254,20 @@ private:
|
|||
Avatar* _interactingOther;
|
||||
bool _interactingOtherIsNearby;
|
||||
float _pelvisStandingHeight;
|
||||
float _height;
|
||||
Balls* _balls;
|
||||
AvatarTouch _avatarTouch;
|
||||
bool _displayingHead; // should be false if in first-person view
|
||||
|
||||
// private methods...
|
||||
void initializeSkeleton();
|
||||
void updateSkeleton();
|
||||
void initializeBodySprings();
|
||||
void updateBodySprings( float deltaTime );
|
||||
void calculateBoneLengths();
|
||||
void readSensors();
|
||||
void updateAvatarCollisionDetectionAndResponse
|
||||
(
|
||||
glm::vec3 collisionPosition,
|
||||
float collisionGirth,
|
||||
float collisionHeight,
|
||||
glm::vec3 collisionUpVector,
|
||||
float deltaTime
|
||||
);
|
||||
// private methods...
|
||||
void initializeSkeleton();
|
||||
void updateSkeleton();
|
||||
void initializeBodySprings();
|
||||
void updateBodySprings( float deltaTime );
|
||||
void calculateBoneLengths();
|
||||
void readSensors();
|
||||
void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime );
|
||||
void updateCollisionWithOtherAvatar( Avatar * other, float deltaTime );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -103,7 +103,7 @@ int HEIGHT = 800;
|
|||
int fullscreen = 0;
|
||||
float aspectRatio = 1.0f;
|
||||
|
||||
bool USING_FIRST_PERSON_EFFECT = true;
|
||||
bool USING_FIRST_PERSON_EFFECT = false;
|
||||
|
||||
bool wantColorRandomizer = true; // for addSphere and load file
|
||||
|
||||
|
|
Loading…
Reference in a new issue