Merge pull request #474 from PhilipRosedale/master

Smooth gravity fields when flying
This commit is contained in:
Andrzej Kapolka 2013-05-31 14:52:00 -07:00
commit 8f377349ef
3 changed files with 40 additions and 18 deletions

View file

@ -25,13 +25,9 @@ using namespace std;
const bool BALLS_ON = false;
const bool USING_AVATAR_GRAVITY = true;
const float GRAVITY_SCALE = 10.0f;
const float BOUNCE = 0.3f;
const float THRUST_MAG = 1200.0;
const glm::vec3 DEFAULT_UP_DIRECTION (0.0f, 1.0f, 0.0f);
const float YAW_MAG = 500.0;
const float BODY_SPIN_FRICTION = 5.0;
const float BODY_UPRIGHT_FORCE = 10.0;
const float VELOCITY_DECAY = 5.0;
const float MY_HAND_HOLDING_PULL = 0.2;
const float YOUR_HAND_HOLDING_PULL = 1.0;
const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f;
@ -88,7 +84,7 @@ Avatar::Avatar(Agent* owningAgent) :
_pelvisFloatingHeight(0.0f),
_distanceToNearestAvatar(std::numeric_limits<float>::max()),
_gravity(0.0f, -1.0f, 0.0f),
_worldUpDirection(0.0f, 1.0f, 0.0),
_worldUpDirection(DEFAULT_UP_DIRECTION),
_mouseRayOrigin(0.0f, 0.0f, 0.0f),
_mouseRayDirection(0.0f, 0.0f, 0.0f),
_interactingOther(NULL),
@ -238,8 +234,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
// apply gravity and collision with the ground/floor
if (!_owningAgent && USING_AVATAR_GRAVITY) {
_velocity += _gravity * (GRAVITY_SCALE * deltaTime);
_velocity += _gravity * (GRAVITY_EARTH * deltaTime);
updateCollisionWithEnvironment();
}
@ -262,6 +257,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
glm::vec3 up = orientation * AVATAR_UP;
// driving the avatar around should only apply if this is my avatar (as opposed to an avatar being driven remotely)
const float THRUST_MAG = 600.0f;
if (!_owningAgent) {
_thrust = glm::vec3(0.0f, 0.0f, 0.0f);
@ -330,7 +327,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f,
BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta)));
// these forces keep the body upright...
// these forces keep the body upright...
const float BODY_UPRIGHT_FORCE = 10.0;
float tiltDecay = BODY_UPRIGHT_FORCE * deltaTime;
if (tiltDecay > 1.0f) {tiltDecay = 1.0f;}
@ -344,6 +342,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
_position += _velocity * deltaTime;
// decay velocity
const float VELOCITY_DECAY = 0.9;
float decay = 1.0 - VELOCITY_DECAY * deltaTime;
if ( decay < 0.0 ) {
_velocity = glm::vec3( 0.0f, 0.0f, 0.0f );
@ -647,12 +646,21 @@ void Avatar::updateCollisionWithVoxels() {
void Avatar::applyCollisionWithScene(const glm::vec3& penetration) {
_position -= penetration;
static float STATIC_FRICTION_VELOCITY = 0.15f;
static float STATIC_FRICTION_DAMPING = 0.0f;
static float KINETIC_FRICTION_DAMPING = 0.95f;
const float BOUNCE = 0.3f;
// reflect the velocity component in the direction of penetration
float penetrationLength = glm::length(penetration);
if (penetrationLength > EPSILON) {
glm::vec3 direction = penetration / penetrationLength;
_velocity -= 2.0f * glm::dot(_velocity, direction) * direction * BOUNCE;
_velocity *= KINETIC_FRICTION_DAMPING;
// If velocity is quite low, apply static friction that takes away energy
if (glm::length(_velocity) < STATIC_FRICTION_VELOCITY) {
_velocity *= STATIC_FRICTION_DAMPING;
}
}
}
@ -755,6 +763,8 @@ void Avatar::setGravity(glm::vec3 gravity) {
float gravityLength = glm::length(gravity);
if (gravityLength > EPSILON) {
_worldUpDirection = _gravity / -gravityLength;
} else {
_worldUpDirection = DEFAULT_UP_DIRECTION;
}
}

View file

@ -58,11 +58,17 @@ void Environment::renderAtmospheres(Camera& camera) {
}
glm::vec3 Environment::getGravity (const glm::vec3& position) {
// the "original gravity"
glm::vec3 gravity;
if (position.x > 0.0f && position.x < EDGE_SIZE_GROUND_PLANE && position.y > 0.0f &&
position.y < 3.0f && position.z > 0.0f && position.z < EDGE_SIZE_GROUND_PLANE) {
gravity = glm::vec3(0.0f, -1.0f, 0.0f);
//
// 'Default' gravity pulls you downward in Y when you are near the X/Z plane
const glm::vec3 DEFAULT_GRAVITY(0.f, -1.f, 0.f);
glm::vec3 gravity(DEFAULT_GRAVITY);
float DEFAULT_SURFACE_RADIUS = 30.f;
float gravityStrength;
// Weaken gravity with height
if (position.y > 0.f) {
gravityStrength = 1.f / powf((DEFAULT_SURFACE_RADIUS + position.y) / DEFAULT_SURFACE_RADIUS, 2.f);
gravity *= gravityStrength;
}
// get the lock for the duration of the call
@ -71,12 +77,18 @@ glm::vec3 Environment::getGravity (const glm::vec3& position) {
foreach (const ServerData& serverData, _data) {
foreach (const EnvironmentData& environmentData, serverData) {
glm::vec3 vector = environmentData.getAtmosphereCenter() - position;
const float GRAVITY_RADIUS_MULTIPLIER = 1.5f;
if (glm::length(vector) < environmentData.getAtmosphereOuterRadius() * GRAVITY_RADIUS_MULTIPLIER) {
float surfaceRadius = environmentData.getAtmosphereInnerRadius();
if (glm::length(vector) <= surfaceRadius) {
// At or inside a planet, gravity is as set for the planet
gravity += glm::normalize(vector) * environmentData.getGravity();
} else {
// Outside a planet, the gravity falls off with distance
gravityStrength = 1.f / powf(glm::length(vector) / surfaceRadius, 2.f);
gravity += glm::normalize(vector) * environmentData.getGravity() * gravityStrength;
}
}
}
return gravity;
}

View file

@ -15,8 +15,8 @@
const float WORLD_SIZE = 10.0;
#define PI 3.14159265
#define PIf 3.14159265f
#define GRAVITY_EARTH 9.80665f;
const float GRAVITY_EARTH = 9.80665f;
const float EDGE_SIZE_GROUND_PLANE = 20.f;
#endif