From 2a9a3139b21cb475decab7e568af9b03b471c001 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 31 May 2013 14:02:20 -0700 Subject: [PATCH] Added smooth gravity field so we can fly to planets and land on them, static friction to stop drifting, thrust tweaks. --- interface/src/Avatar.cpp | 30 ++++++++++++++++++++---------- interface/src/Environment.cpp | 26 +++++++++++++++++++------- interface/src/world.h | 2 +- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 3a4162d296..4dd95d6a16 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -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::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; } } diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index f762aaeed1..d087281569 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -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; } diff --git a/interface/src/world.h b/interface/src/world.h index c0c514c26d..950068ca73 100644 --- a/interface/src/world.h +++ b/interface/src/world.h @@ -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