mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 23:32:48 +02:00
More reliable floor detection for avatar movement.
Also tweaked max walking speed.
This commit is contained in:
parent
908f4f3a5e
commit
b2432876ce
3 changed files with 108 additions and 154 deletions
|
@ -49,7 +49,7 @@ const float PITCH_SPEED = 100.0f; // degrees/sec
|
||||||
const float COLLISION_RADIUS_SCALAR = 1.2f; // pertains to avatar-to-avatar collisions
|
const float COLLISION_RADIUS_SCALAR = 1.2f; // pertains to avatar-to-avatar collisions
|
||||||
const float COLLISION_RADIUS_SCALE = 0.125f;
|
const float COLLISION_RADIUS_SCALE = 0.125f;
|
||||||
|
|
||||||
const float MIN_KEYBOARD_CONTROL_SPEED = 2.0f;
|
const float MIN_KEYBOARD_CONTROL_SPEED = 1.5f;
|
||||||
const float MAX_WALKING_SPEED = 3.0f * MIN_KEYBOARD_CONTROL_SPEED;
|
const float MAX_WALKING_SPEED = 3.0f * MIN_KEYBOARD_CONTROL_SPEED;
|
||||||
|
|
||||||
// TODO: normalize avatar speed for standard avatar size, then scale all motion logic
|
// TODO: normalize avatar speed for standard avatar size, then scale all motion logic
|
||||||
|
@ -75,7 +75,6 @@ MyAvatar::MyAvatar() :
|
||||||
_motorTimescale(DEFAULT_MOTOR_TIMESCALE),
|
_motorTimescale(DEFAULT_MOTOR_TIMESCALE),
|
||||||
_maxMotorSpeed(MAX_MOTOR_SPEED),
|
_maxMotorSpeed(MAX_MOTOR_SPEED),
|
||||||
_motionBehaviors(AVATAR_MOTION_DEFAULTS),
|
_motionBehaviors(AVATAR_MOTION_DEFAULTS),
|
||||||
_lastFloorContactPoint(0.0f),
|
|
||||||
_lookAtTargetAvatar(),
|
_lookAtTargetAvatar(),
|
||||||
_shouldRender(true),
|
_shouldRender(true),
|
||||||
_billboardValid(false),
|
_billboardValid(false),
|
||||||
|
@ -1085,15 +1084,6 @@ bool MyAvatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode rend
|
||||||
(glm::length(cameraPosition - head->getEyePosition()) > RENDER_HEAD_CUTOFF_DISTANCE * _scale);
|
(glm::length(cameraPosition - head->getEyePosition()) > RENDER_HEAD_CUTOFF_DISTANCE * _scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
float MyAvatar::computeDistanceToFloor(const glm::vec3& startPoint) {
|
|
||||||
glm::vec3 direction = -_worldUpDirection;
|
|
||||||
OctreeElement* elementHit; // output from findRayIntersection
|
|
||||||
float distance = FLT_MAX; // output from findRayIntersection
|
|
||||||
BoxFace face; // output from findRayIntersection
|
|
||||||
Application::getInstance()->getVoxelTree()->findRayIntersection(startPoint, direction, elementHit, distance, face);
|
|
||||||
return distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyAvatar::updateOrientation(float deltaTime) {
|
void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
// Gather rotation information from keyboard
|
// Gather rotation information from keyboard
|
||||||
_bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_SPEED * deltaTime;
|
_bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_SPEED * deltaTime;
|
||||||
|
@ -1151,86 +1141,69 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
const float NEARBY_FLOOR_THRESHOLD = 5.0f;
|
const float NEARBY_FLOOR_THRESHOLD = 5.0f;
|
||||||
|
|
||||||
void MyAvatar::updatePosition(float deltaTime) {
|
void MyAvatar::updatePosition(float deltaTime) {
|
||||||
float keyboardInput = fabsf(_driveKeys[FWD] - _driveKeys[BACK]) +
|
|
||||||
fabsf(_driveKeys[RIGHT] - _driveKeys[LEFT]) +
|
|
||||||
fabsf(_driveKeys[UP] - _driveKeys[DOWN]);
|
|
||||||
|
|
||||||
bool walkingOnFloor = false;
|
|
||||||
float gravityLength = glm::length(_gravity) * GRAVITY_EARTH;
|
|
||||||
|
|
||||||
|
// check for floor by casting a ray straight down from avatar's position
|
||||||
|
float heightAboveFloor = FLT_MAX;
|
||||||
const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape();
|
const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape();
|
||||||
glm::vec3 startCap;
|
RayIntersectionInfo intersection;
|
||||||
boundingShape.getStartPoint(startCap);
|
// NOTE: avatar is center of PhysicsSimulation, so rayStart is the origin for the purposes of the raycast
|
||||||
glm::vec3 bottom = startCap - boundingShape.getRadius() * _worldUpDirection;
|
intersection._rayStart = glm::vec3(0.0f);
|
||||||
|
intersection._rayDirection = - _worldUpDirection;
|
||||||
|
intersection._rayLength = 5.0f * boundingShape.getBoundingRadius();
|
||||||
|
if (_physicsSimulation.findFloorRayIntersection(intersection)) {
|
||||||
|
// NOTE: heightAboveFloor is the distance between the bottom of the avatar and the floor
|
||||||
|
heightAboveFloor = intersection._hitDistance - boundingShape.getBoundingRadius();
|
||||||
|
}
|
||||||
|
|
||||||
// velocity is initialized to the measured _velocity but will be modified
|
// velocity is initialized to the measured _velocity but will be modified by friction, external thrust, etc
|
||||||
// by friction, external thrust, etc
|
|
||||||
glm::vec3 velocity = _velocity;
|
glm::vec3 velocity = _velocity;
|
||||||
|
|
||||||
// apply friction
|
bool pushingUp = (_driveKeys[UP] - _driveKeys[DOWN] > 0.0f);
|
||||||
if (gravityLength > EPSILON) {
|
bool walkingOnFloor = false;
|
||||||
float speedFromGravity = _scale * deltaTime * gravityLength;
|
if (_motionBehaviors & AVATAR_MOTION_STAND_ON_NEARBY_FLOORS) {
|
||||||
float distanceToFall = glm::distance(bottom, _lastFloorContactPoint);
|
const float MAX_SPEED_UNDER_GRAVITY = 2.0f * _scale * MAX_WALKING_SPEED;
|
||||||
walkingOnFloor = (distanceToFall < 2.0f * deltaTime * speedFromGravity);
|
if (pushingUp || glm::length2(velocity) > MAX_SPEED_UNDER_GRAVITY * MAX_SPEED_UNDER_GRAVITY) {
|
||||||
|
// we're pushing up or moving quickly, so disable gravity
|
||||||
if (walkingOnFloor) {
|
setLocalGravity(glm::vec3(0.0f));
|
||||||
// BEGIN HACK: to prevent the avatar from bouncing on a floor surface
|
|
||||||
if (distanceToFall < deltaTime * speedFromGravity) {
|
|
||||||
float verticalSpeed = glm::dot(velocity, _worldUpDirection);
|
|
||||||
if (fabs(verticalSpeed) < speedFromGravity) {
|
|
||||||
// we're standing on a floor, and nearly at rest so we zero the vertical velocity component
|
|
||||||
velocity -= verticalSpeed * _worldUpDirection;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// fall with gravity against floor
|
|
||||||
velocity -= speedFromGravity * _worldUpDirection;
|
|
||||||
}
|
|
||||||
// END HACK
|
|
||||||
} else {
|
} else {
|
||||||
if (!_isBraking) {
|
const float maxFloorDistance = boundingShape.getBoundingRadius() * NEARBY_FLOOR_THRESHOLD;
|
||||||
// fall with gravity toward floor
|
if (heightAboveFloor > maxFloorDistance) {
|
||||||
velocity -= speedFromGravity * _worldUpDirection;
|
// disable local gravity when floor is too far away
|
||||||
}
|
setLocalGravity(glm::vec3(0.0f));
|
||||||
|
} else {
|
||||||
if (_motionBehaviors & AVATAR_MOTION_STAND_ON_NEARBY_FLOORS) {
|
// enable gravity
|
||||||
const float MAX_VERTICAL_FLOOR_DETECTION_SPEED = _scale * MAX_WALKING_SPEED;
|
walkingOnFloor = true;
|
||||||
if (keyboardInput && glm::dot(_motorVelocity, _worldUpDirection) > 0.0f &&
|
|
||||||
glm::dot(velocity, _worldUpDirection) > MAX_VERTICAL_FLOOR_DETECTION_SPEED) {
|
|
||||||
// disable local gravity when flying up
|
|
||||||
setLocalGravity(glm::vec3(0.0f));
|
|
||||||
} else {
|
|
||||||
const float maxFloorDistance = _scale * NEARBY_FLOOR_THRESHOLD;
|
|
||||||
if (computeDistanceToFloor(bottom) > maxFloorDistance) {
|
|
||||||
// disable local gravity when floor is too far
|
|
||||||
setLocalGravity(glm::vec3(0.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ((_collisionGroups & COLLISION_GROUP_VOXELS) &&
|
|
||||||
_motionBehaviors & AVATAR_MOTION_STAND_ON_NEARBY_FLOORS) {
|
|
||||||
const float MIN_FLOOR_DETECTION_SPEED = _scale * 1.0f;
|
|
||||||
if (glm::length(_velocity) < MIN_FLOOR_DETECTION_SPEED ) {
|
|
||||||
// scan for floor under avatar
|
|
||||||
const float maxFloorDistance = _scale * NEARBY_FLOOR_THRESHOLD;
|
|
||||||
if (computeDistanceToFloor(bottom) < maxFloorDistance) {
|
|
||||||
// enable local gravity
|
|
||||||
setLocalGravity(-_worldUpDirection);
|
setLocalGravity(-_worldUpDirection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float speed = glm::length(velocity);
|
bool zeroDownwardVelocity = false;
|
||||||
if (keyboardInput > 0.0f || speed > 0.0f || glm::length2(_thrust) > 0.0f || ! walkingOnFloor) {
|
bool gravityEnabled = (glm::length2(_gravity) > EPSILON);
|
||||||
// update motor
|
if (gravityEnabled) {
|
||||||
if (_motionBehaviors & AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED) {
|
if (heightAboveFloor < 0.0f) {
|
||||||
// Increase motor velocity until its length is equal to _maxMotorSpeed.
|
// Gravity is in effect so we assume that the avatar is colliding against the world and we need
|
||||||
glm::vec3 localVelocity = velocity;
|
// to lift avatar out of floor, but we don't want to do it too fast (keep it smooth).
|
||||||
if (_motionBehaviors & AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME) {
|
float distanceToLift = glm::min(-heightAboveFloor, MAX_WALKING_SPEED * deltaTime);
|
||||||
glm::quat orientation = getHead()->getCameraOrientation();
|
|
||||||
localVelocity = glm::inverse(orientation) * velocity;
|
// We don't use applyPositionDelta() for this lift distance because we don't want the avatar
|
||||||
}
|
// to come flying out of the floor. Instead we update position directly, and set a boolean
|
||||||
|
// that will remind us later to zero any downward component of the velocity.
|
||||||
|
_position += (distanceToLift - EPSILON) * _worldUpDirection;
|
||||||
|
zeroDownwardVelocity = true;
|
||||||
|
}
|
||||||
|
velocity += (deltaTime * GRAVITY_EARTH) * _gravity;
|
||||||
|
}
|
||||||
|
|
||||||
|
float motorEfficiency = glm::clamp(deltaTime / computeMotorTimescale(velocity), 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// compute targetVelocity
|
||||||
|
glm::vec3 targetVelocity(0.0f);
|
||||||
|
if (_motionBehaviors & AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED) {
|
||||||
|
float keyboardInput = fabsf(_driveKeys[FWD] - _driveKeys[BACK]) +
|
||||||
|
(fabsf(_driveKeys[RIGHT] - _driveKeys[LEFT])) +
|
||||||
|
fabsf(_driveKeys[UP] - _driveKeys[DOWN]);
|
||||||
|
if (keyboardInput) {
|
||||||
// Compute keyboard input
|
// Compute keyboard input
|
||||||
glm::vec3 front = (_driveKeys[FWD] - _driveKeys[BACK]) * IDENTITY_FRONT;
|
glm::vec3 front = (_driveKeys[FWD] - _driveKeys[BACK]) * IDENTITY_FRONT;
|
||||||
glm::vec3 right = (_driveKeys[RIGHT] - _driveKeys[LEFT]) * IDENTITY_RIGHT;
|
glm::vec3 right = (_driveKeys[RIGHT] - _driveKeys[LEFT]) * IDENTITY_RIGHT;
|
||||||
|
@ -1242,76 +1215,69 @@ void MyAvatar::updatePosition(float deltaTime) {
|
||||||
// Compute motor magnitude
|
// Compute motor magnitude
|
||||||
if (directionLength > EPSILON) {
|
if (directionLength > EPSILON) {
|
||||||
direction /= directionLength;
|
direction /= directionLength;
|
||||||
// the finalMotorSpeed depends on whether we are walking or not
|
|
||||||
|
// Compute the target keyboard velocity (which ramps up slowly, and damps very quickly)
|
||||||
|
// the max magnitude of which depends on what we're doing:
|
||||||
float finalMaxMotorSpeed = walkingOnFloor ? _scale * MAX_WALKING_SPEED : _scale * _maxMotorSpeed;
|
float finalMaxMotorSpeed = walkingOnFloor ? _scale * MAX_WALKING_SPEED : _scale * _maxMotorSpeed;
|
||||||
|
|
||||||
float motorLength = glm::length(_motorVelocity);
|
float motorLength = glm::length(_motorVelocity);
|
||||||
if (motorLength < _scale * MIN_KEYBOARD_CONTROL_SPEED) {
|
if (motorLength < _scale * MIN_KEYBOARD_CONTROL_SPEED) {
|
||||||
// an active keyboard motor should never be slower than this
|
// an active keyboard motor should never be slower than this
|
||||||
_motorVelocity = _scale * MIN_KEYBOARD_CONTROL_SPEED * direction;
|
_motorVelocity = _scale * MIN_KEYBOARD_CONTROL_SPEED * direction;
|
||||||
|
motorEfficiency = 1.0f;
|
||||||
} else {
|
} else {
|
||||||
float MOTOR_LENGTH_TIMESCALE = 1.5f;
|
float MOTOR_LENGTH_TIMESCALE = 2.0f;
|
||||||
float tau = glm::clamp(deltaTime / MOTOR_LENGTH_TIMESCALE, 0.0f, 1.0f);
|
float INCREASE_FACTOR = 1.8f;
|
||||||
float INCREASE_FACTOR = 2.0f;
|
motorLength *= 1.0f + glm::clamp(deltaTime / MOTOR_LENGTH_TIMESCALE, 0.0f, 1.0f) * INCREASE_FACTOR;
|
||||||
//_motorVelocity *= 1.0f + tau * INCREASE_FACTOR;
|
|
||||||
motorLength *= 1.0f + tau * INCREASE_FACTOR;
|
|
||||||
if (motorLength > finalMaxMotorSpeed) {
|
if (motorLength > finalMaxMotorSpeed) {
|
||||||
motorLength = finalMaxMotorSpeed;
|
motorLength = finalMaxMotorSpeed;
|
||||||
}
|
}
|
||||||
_motorVelocity = motorLength * direction;
|
_motorVelocity = motorLength * direction;
|
||||||
}
|
}
|
||||||
_isPushing = true;
|
_isPushing = true;
|
||||||
} else {
|
}
|
||||||
// motor opposes motion (wants to be at rest)
|
targetVelocity = _motorVelocity;
|
||||||
_motorVelocity = - localVelocity;
|
} else {
|
||||||
}
|
_motorVelocity = glm::vec3(0.0f);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
targetVelocity = getHead()->getCameraOrientation() * targetVelocity;
|
||||||
|
|
||||||
// apply motor
|
glm::vec3 deltaVelocity = targetVelocity - velocity;
|
||||||
if (_motionBehaviors & AVATAR_MOTION_MOTOR_ENABLED) {
|
|
||||||
glm::vec3 targetVelocity = _motorVelocity;
|
|
||||||
if (_motionBehaviors & AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME) {
|
|
||||||
// rotate targetVelocity into world frame
|
|
||||||
glm::quat rotation = getHead()->getCameraOrientation();
|
|
||||||
targetVelocity = rotation * _motorVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 deltaVelocity = targetVelocity - velocity;
|
|
||||||
|
|
||||||
if (_motionBehaviors & AVATAR_MOTION_MOTOR_COLLISION_SURFACE_ONLY && glm::length2(_gravity) > EPSILON) {
|
|
||||||
// For now we subtract the component parallel to gravity but what we need to do is:
|
|
||||||
// TODO: subtract the component perp to the local surface normal (motor only pushes in surface plane).
|
|
||||||
glm::vec3 gravityDirection = glm::normalize(_gravity);
|
|
||||||
glm::vec3 parallelDelta = glm::dot(deltaVelocity, gravityDirection) * gravityDirection;
|
|
||||||
if (glm::dot(targetVelocity, velocity) > 0.0f) {
|
|
||||||
// remove parallel part from deltaVelocity
|
|
||||||
deltaVelocity -= parallelDelta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// simple critical damping
|
|
||||||
float timescale = computeMotorTimescale(velocity);
|
|
||||||
float tau = glm::clamp(deltaTime / timescale, 0.0f, 1.0f);
|
|
||||||
velocity += tau * deltaVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// apply thrust
|
if (walkingOnFloor && !pushingUp) {
|
||||||
velocity += _thrust * deltaTime;
|
// remove vertical component of deltaVelocity
|
||||||
speed = glm::length(velocity);
|
deltaVelocity -= glm::dot(deltaVelocity, _worldUpDirection) * _worldUpDirection;
|
||||||
if (speed > MAX_AVATAR_SPEED) {
|
}
|
||||||
velocity *= MAX_AVATAR_SPEED / speed;
|
|
||||||
speed = MAX_AVATAR_SPEED;
|
|
||||||
}
|
|
||||||
_thrust = glm::vec3(0.0f);
|
|
||||||
|
|
||||||
// update position
|
// apply motor
|
||||||
const float MIN_AVATAR_SPEED = 0.075f;
|
velocity += motorEfficiency * deltaVelocity;
|
||||||
if (speed > MIN_AVATAR_SPEED) {
|
|
||||||
applyPositionDelta(deltaTime * velocity);
|
// apply thrust
|
||||||
|
velocity += _thrust * deltaTime;
|
||||||
|
_thrust = glm::vec3(0.0f);
|
||||||
|
|
||||||
|
// remove downward velocity so we don't push into floor
|
||||||
|
if (zeroDownwardVelocity) {
|
||||||
|
float verticalSpeed = glm::dot(velocity, _worldUpDirection);
|
||||||
|
if (verticalSpeed < 0.0f) {
|
||||||
|
velocity += verticalSpeed * _worldUpDirection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update moving flag based on speed
|
// cap avatar speed
|
||||||
|
float speed = glm::length(velocity);
|
||||||
|
if (speed > MAX_AVATAR_SPEED) {
|
||||||
|
velocity *= MAX_AVATAR_SPEED / speed;
|
||||||
|
speed = MAX_AVATAR_SPEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update position
|
||||||
|
const float MIN_AVATAR_SPEED = 0.075f;
|
||||||
|
if (speed > MIN_AVATAR_SPEED) {
|
||||||
|
applyPositionDelta(deltaTime * velocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update _moving flag based on speed
|
||||||
const float MOVING_SPEED_THRESHOLD = 0.01f;
|
const float MOVING_SPEED_THRESHOLD = 0.01f;
|
||||||
_moving = speed > MOVING_SPEED_THRESHOLD;
|
_moving = speed > MOVING_SPEED_THRESHOLD;
|
||||||
|
|
||||||
|
@ -1330,8 +1296,8 @@ float MyAvatar::computeMotorTimescale(const glm::vec3& velocity) {
|
||||||
// (3) inactive --> long timescale (gentle friction for low speeds)
|
// (3) inactive --> long timescale (gentle friction for low speeds)
|
||||||
|
|
||||||
float MIN_MOTOR_TIMESCALE = 0.125f;
|
float MIN_MOTOR_TIMESCALE = 0.125f;
|
||||||
float MAX_MOTOR_TIMESCALE = 0.5f;
|
float MAX_MOTOR_TIMESCALE = 0.4f;
|
||||||
float MIN_BRAKE_SPEED = 0.4f;
|
float MIN_BRAKE_SPEED = 0.3f;
|
||||||
|
|
||||||
float timescale = MAX_MOTOR_TIMESCALE;
|
float timescale = MAX_MOTOR_TIMESCALE;
|
||||||
bool isThrust = (glm::length2(_thrust) > EPSILON);
|
bool isThrust = (glm::length2(_thrust) > EPSILON);
|
||||||
|
@ -1372,7 +1338,7 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) {
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
if (_voxelShapeManager.needsUpdate(now)) {
|
if (_voxelShapeManager.needsUpdate(now)) {
|
||||||
// We use a multiple of the avatar's boundingRadius as the size of the cube of interest.
|
// We use a multiple of the avatar's boundingRadius as the size of the cube of interest.
|
||||||
float cubeScale = 4.0f * getBoundingRadius();
|
float cubeScale = 6.0f * getBoundingRadius();
|
||||||
glm::vec3 corner = getPosition() - glm::vec3(0.5f * cubeScale);
|
glm::vec3 corner = getPosition() - glm::vec3(0.5f * cubeScale);
|
||||||
AACube boundingCube(corner, cubeScale);
|
AACube boundingCube(corner, cubeScale);
|
||||||
|
|
||||||
|
@ -1459,9 +1425,6 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lowestStep < MAX_STEP_HEIGHT) {
|
|
||||||
_lastFloorContactPoint = floorPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
float penetrationLength = glm::length(totalPenetration);
|
float penetrationLength = glm::length(totalPenetration);
|
||||||
if (penetrationLength < EPSILON) {
|
if (penetrationLength < EPSILON) {
|
||||||
|
@ -1471,12 +1434,11 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) {
|
||||||
float verticalPenetration = glm::dot(totalPenetration, _worldUpDirection);
|
float verticalPenetration = glm::dot(totalPenetration, _worldUpDirection);
|
||||||
if (highestStep > MIN_STEP_HEIGHT && highestStep < MAX_STEP_HEIGHT && verticalPenetration <= 0.0f) {
|
if (highestStep > MIN_STEP_HEIGHT && highestStep < MAX_STEP_HEIGHT && verticalPenetration <= 0.0f) {
|
||||||
// we're colliding against an edge
|
// we're colliding against an edge
|
||||||
|
|
||||||
|
// rotate _motorVelocity into world frame
|
||||||
glm::vec3 targetVelocity = _motorVelocity;
|
glm::vec3 targetVelocity = _motorVelocity;
|
||||||
if (_motionBehaviors & AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME) {
|
glm::quat rotation = getHead()->getCameraOrientation();
|
||||||
// rotate _motorVelocity into world frame
|
targetVelocity = rotation * _motorVelocity;
|
||||||
glm::quat rotation = getHead()->getCameraOrientation();
|
|
||||||
targetVelocity = rotation * _motorVelocity;
|
|
||||||
}
|
|
||||||
if (_wasPushing && glm::dot(targetVelocity, totalPenetration) > EPSILON) {
|
if (_wasPushing && glm::dot(targetVelocity, totalPenetration) > EPSILON) {
|
||||||
// we're puhing into the edge, so we want to lift
|
// we're puhing into the edge, so we want to lift
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,6 @@ private:
|
||||||
float _maxMotorSpeed;
|
float _maxMotorSpeed;
|
||||||
quint32 _motionBehaviors;
|
quint32 _motionBehaviors;
|
||||||
|
|
||||||
glm::vec3 _lastFloorContactPoint;
|
|
||||||
QWeakPointer<AvatarData> _lookAtTargetAvatar;
|
QWeakPointer<AvatarData> _lookAtTargetAvatar;
|
||||||
glm::vec3 _targetAvatarPosition;
|
glm::vec3 _targetAvatarPosition;
|
||||||
bool _shouldRender;
|
bool _shouldRender;
|
||||||
|
@ -221,7 +220,6 @@ private:
|
||||||
RecorderPointer _recorder;
|
RecorderPointer _recorder;
|
||||||
|
|
||||||
// private methods
|
// private methods
|
||||||
float computeDistanceToFloor(const glm::vec3& startPoint);
|
|
||||||
void updateOrientation(float deltaTime);
|
void updateOrientation(float deltaTime);
|
||||||
void updatePosition(float deltaTime);
|
void updatePosition(float deltaTime);
|
||||||
float computeMotorTimescale(const glm::vec3& velocity);
|
float computeMotorTimescale(const glm::vec3& velocity);
|
||||||
|
|
|
@ -55,20 +55,14 @@ typedef unsigned long long quint64;
|
||||||
#include "HandData.h"
|
#include "HandData.h"
|
||||||
|
|
||||||
// avatar motion behaviors
|
// avatar motion behaviors
|
||||||
const quint32 AVATAR_MOTION_MOTOR_ENABLED = 1U << 0;
|
const quint32 AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED = 1U << 0;
|
||||||
const quint32 AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED = 1U << 1;
|
|
||||||
const quint32 AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME = 1U << 2;
|
|
||||||
const quint32 AVATAR_MOTION_MOTOR_COLLISION_SURFACE_ONLY = 1U << 3;
|
|
||||||
|
|
||||||
const quint32 AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY = 1U << 4;
|
const quint32 AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY = 1U << 1;
|
||||||
const quint32 AVATAR_MOTION_OBEY_LOCAL_GRAVITY = 1U << 5;
|
const quint32 AVATAR_MOTION_OBEY_LOCAL_GRAVITY = 1U << 2;
|
||||||
|
const quint32 AVATAR_MOTION_STAND_ON_NEARBY_FLOORS = 1U << 3;
|
||||||
const quint32 AVATAR_MOTION_STAND_ON_NEARBY_FLOORS = 1U << 6;
|
|
||||||
|
|
||||||
const quint32 AVATAR_MOTION_DEFAULTS =
|
const quint32 AVATAR_MOTION_DEFAULTS =
|
||||||
AVATAR_MOTION_MOTOR_ENABLED |
|
|
||||||
AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED |
|
AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED |
|
||||||
AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME |
|
|
||||||
AVATAR_MOTION_STAND_ON_NEARBY_FLOORS;
|
AVATAR_MOTION_STAND_ON_NEARBY_FLOORS;
|
||||||
|
|
||||||
// these bits will be expanded as features are exposed
|
// these bits will be expanded as features are exposed
|
||||||
|
|
Loading…
Reference in a new issue