mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 10:47:11 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi
This commit is contained in:
commit
84b78429f2
14 changed files with 177 additions and 92 deletions
|
@ -735,7 +735,7 @@ void DomainServer::setupPendingAssignmentCredits() {
|
||||||
|
|
||||||
const float CREDITS_PER_HOUR = 0.10f;
|
const float CREDITS_PER_HOUR = 0.10f;
|
||||||
const float CREDITS_PER_MSEC = CREDITS_PER_HOUR / (60 * 60 * 1000);
|
const float CREDITS_PER_MSEC = CREDITS_PER_HOUR / (60 * 60 * 1000);
|
||||||
const int SATOSHIS_PER_MSEC = CREDITS_PER_MSEC * powf(10.0f, 8.0f);
|
const int SATOSHIS_PER_MSEC = CREDITS_PER_MSEC * SATOSHIS_PER_CREDIT;
|
||||||
|
|
||||||
float pendingCredits = elapsedMsecsSinceLastPayment * SATOSHIS_PER_MSEC;
|
float pendingCredits = elapsedMsecsSinceLastPayment * SATOSHIS_PER_MSEC;
|
||||||
|
|
||||||
|
@ -884,10 +884,10 @@ QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
|
||||||
|
|
||||||
if (!nodeData->getWalletUUID().isNull()) {
|
if (!nodeData->getWalletUUID().isNull()) {
|
||||||
TransactionHash::iterator i = _pendingAssignmentCredits.find(nodeData->getWalletUUID());
|
TransactionHash::iterator i = _pendingAssignmentCredits.find(nodeData->getWalletUUID());
|
||||||
double pendingCreditAmount = 0;
|
float pendingCreditAmount = 0;
|
||||||
|
|
||||||
while (i != _pendingAssignmentCredits.end() && i.key() == nodeData->getWalletUUID()) {
|
while (i != _pendingAssignmentCredits.end() && i.key() == nodeData->getWalletUUID()) {
|
||||||
pendingCreditAmount += i.value()->getAmount();
|
pendingCreditAmount += i.value()->getAmount() / (float) SATOSHIS_PER_CREDIT;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,13 +18,13 @@
|
||||||
WalletTransaction::WalletTransaction() :
|
WalletTransaction::WalletTransaction() :
|
||||||
_uuid(),
|
_uuid(),
|
||||||
_destinationUUID(),
|
_destinationUUID(),
|
||||||
_amount(),
|
_amount(0),
|
||||||
_isFinalized(false)
|
_isFinalized(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletTransaction::WalletTransaction(const QUuid& destinationUUID, double amount) :
|
WalletTransaction::WalletTransaction(const QUuid& destinationUUID, qint64 amount) :
|
||||||
_uuid(QUuid::createUuid()),
|
_uuid(QUuid::createUuid()),
|
||||||
_destinationUUID(destinationUUID),
|
_destinationUUID(destinationUUID),
|
||||||
_amount(amount),
|
_amount(amount),
|
||||||
|
@ -63,5 +63,5 @@ void WalletTransaction::loadFromJson(const QJsonObject& jsonObject) {
|
||||||
|
|
||||||
_uuid = QUuid(transactionObject.value(TRANSACTION_ID_KEY).toString());
|
_uuid = QUuid(transactionObject.value(TRANSACTION_ID_KEY).toString());
|
||||||
_destinationUUID = QUuid(transactionObject.value(TRANSACTION_DESTINATION_WALLET_ID_KEY).toString());
|
_destinationUUID = QUuid(transactionObject.value(TRANSACTION_DESTINATION_WALLET_ID_KEY).toString());
|
||||||
_amount = transactionObject.value(TRANSACTION_AMOUNT_KEY).toDouble();
|
_amount = transactionObject.value(TRANSACTION_AMOUNT_KEY).toInt();
|
||||||
}
|
}
|
|
@ -19,16 +19,16 @@
|
||||||
class WalletTransaction : public QObject {
|
class WalletTransaction : public QObject {
|
||||||
public:
|
public:
|
||||||
WalletTransaction();
|
WalletTransaction();
|
||||||
WalletTransaction(const QUuid& destinationUUID, double amount);
|
WalletTransaction(const QUuid& destinationUUID, qint64 amount);
|
||||||
|
|
||||||
const QUuid& getUUID() const { return _uuid; }
|
const QUuid& getUUID() const { return _uuid; }
|
||||||
|
|
||||||
void setDestinationUUID(const QUuid& destinationUUID) { _destinationUUID = destinationUUID; }
|
void setDestinationUUID(const QUuid& destinationUUID) { _destinationUUID = destinationUUID; }
|
||||||
const QUuid& getDestinationUUID() const { return _destinationUUID; }
|
const QUuid& getDestinationUUID() const { return _destinationUUID; }
|
||||||
|
|
||||||
double getAmount() const { return _amount; }
|
qint64 getAmount() const { return _amount; }
|
||||||
void setAmount(double amount) { _amount = amount; }
|
void setAmount(qint64 amount) { _amount = amount; }
|
||||||
void incrementAmount(double increment) { _amount += increment; }
|
void incrementAmount(qint64 increment) { _amount += increment; }
|
||||||
|
|
||||||
bool isFinalized() const { return _isFinalized; }
|
bool isFinalized() const { return _isFinalized; }
|
||||||
void setIsFinalized(bool isFinalized) { _isFinalized = isFinalized; }
|
void setIsFinalized(bool isFinalized) { _isFinalized = isFinalized; }
|
||||||
|
@ -39,7 +39,7 @@ public:
|
||||||
private:
|
private:
|
||||||
QUuid _uuid;
|
QUuid _uuid;
|
||||||
QUuid _destinationUUID;
|
QUuid _destinationUUID;
|
||||||
double _amount;
|
qint64 _amount;
|
||||||
bool _isFinalized;
|
bool _isFinalized;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2534,6 +2534,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||||
if (_voxelFades.size() > 0) {
|
if (_voxelFades.size() > 0) {
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
"Application::displaySide() ... voxel fades...");
|
"Application::displaySide() ... voxel fades...");
|
||||||
|
_voxelFadesLock.lockForWrite();
|
||||||
for(std::vector<VoxelFade>::iterator fade = _voxelFades.begin(); fade != _voxelFades.end();) {
|
for(std::vector<VoxelFade>::iterator fade = _voxelFades.begin(); fade != _voxelFades.end();) {
|
||||||
fade->render();
|
fade->render();
|
||||||
if(fade->isDone()) {
|
if(fade->isDone()) {
|
||||||
|
@ -2542,6 +2543,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||||
++fade;
|
++fade;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_voxelFadesLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// give external parties a change to hook in
|
// give external parties a change to hook in
|
||||||
|
@ -3106,7 +3108,7 @@ void Application::updateWindowTitle(){
|
||||||
|
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
if (accountManager.getAccountInfo().hasBalance()) {
|
if (accountManager.getAccountInfo().hasBalance()) {
|
||||||
float creditBalance = accountManager.getAccountInfo().getBalance() * pow(10.0f, -8.0f);
|
float creditBalance = accountManager.getAccountInfo().getBalance() / (float) SATOSHIS_PER_CREDIT;
|
||||||
|
|
||||||
QString creditBalanceString;
|
QString creditBalanceString;
|
||||||
creditBalanceString.sprintf("%.8f", creditBalance);
|
creditBalanceString.sprintf("%.8f", creditBalance);
|
||||||
|
@ -3208,7 +3210,9 @@ void Application::nodeKilled(SharedNodePointer node) {
|
||||||
fade.voxelDetails = rootDetails;
|
fade.voxelDetails = rootDetails;
|
||||||
const float slightly_smaller = 0.99f;
|
const float slightly_smaller = 0.99f;
|
||||||
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
|
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
|
||||||
|
_voxelFadesLock.lockForWrite();
|
||||||
_voxelFades.push_back(fade);
|
_voxelFades.push_back(fade);
|
||||||
|
_voxelFadesLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the voxel server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
|
// If the voxel server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
|
||||||
|
@ -3239,7 +3243,9 @@ void Application::nodeKilled(SharedNodePointer node) {
|
||||||
fade.voxelDetails = rootDetails;
|
fade.voxelDetails = rootDetails;
|
||||||
const float slightly_smaller = 0.99f;
|
const float slightly_smaller = 0.99f;
|
||||||
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
|
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
|
||||||
|
_voxelFadesLock.lockForWrite();
|
||||||
_voxelFades.push_back(fade);
|
_voxelFades.push_back(fade);
|
||||||
|
_voxelFadesLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the particle server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
|
// If the particle server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
|
||||||
|
@ -3271,7 +3277,9 @@ void Application::nodeKilled(SharedNodePointer node) {
|
||||||
fade.voxelDetails = rootDetails;
|
fade.voxelDetails = rootDetails;
|
||||||
const float slightly_smaller = 0.99f;
|
const float slightly_smaller = 0.99f;
|
||||||
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
|
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
|
||||||
|
_voxelFadesLock.lockForWrite();
|
||||||
_voxelFades.push_back(fade);
|
_voxelFades.push_back(fade);
|
||||||
|
_voxelFadesLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the model server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
|
// If the model server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
|
||||||
|
@ -3356,7 +3364,9 @@ int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePoin
|
||||||
fade.voxelDetails = rootDetails;
|
fade.voxelDetails = rootDetails;
|
||||||
const float slightly_smaller = 0.99f;
|
const float slightly_smaller = 0.99f;
|
||||||
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
|
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
|
||||||
|
_voxelFadesLock.lockForWrite();
|
||||||
_voxelFades.push_back(fade);
|
_voxelFades.push_back(fade);
|
||||||
|
_voxelFadesLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// store jurisdiction details for later use
|
// store jurisdiction details for later use
|
||||||
|
|
|
@ -533,6 +533,7 @@ private:
|
||||||
NodeBounds _nodeBoundsDisplay;
|
NodeBounds _nodeBoundsDisplay;
|
||||||
|
|
||||||
std::vector<VoxelFade> _voxelFades;
|
std::vector<VoxelFade> _voxelFades;
|
||||||
|
QReadWriteLock _voxelFadesLock;
|
||||||
ControllerScriptingInterface _controllerScriptingInterface;
|
ControllerScriptingInterface _controllerScriptingInterface;
|
||||||
QPointer<LogDialog> _logDialog;
|
QPointer<LogDialog> _logDialog;
|
||||||
QPointer<SnapshotShareDialog> _snapshotShareDialog;
|
QPointer<SnapshotShareDialog> _snapshotShareDialog;
|
||||||
|
|
|
@ -200,7 +200,8 @@ Menu::Menu() :
|
||||||
QObject* avatar = appInstance->getAvatar();
|
QObject* avatar = appInstance->getAvatar();
|
||||||
addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::ObeyEnvironmentalGravity, Qt::SHIFT | Qt::Key_G, false,
|
addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::ObeyEnvironmentalGravity, Qt::SHIFT | Qt::Key_G, false,
|
||||||
avatar, SLOT(updateMotionBehaviorsFromMenu()));
|
avatar, SLOT(updateMotionBehaviorsFromMenu()));
|
||||||
|
addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::StandOnNearbyFloors, 0, true,
|
||||||
|
avatar, SLOT(updateMotionBehaviorsFromMenu()));
|
||||||
|
|
||||||
addAvatarCollisionSubMenu(editMenu);
|
addAvatarCollisionSubMenu(editMenu);
|
||||||
|
|
||||||
|
|
|
@ -376,6 +376,7 @@ namespace MenuOption {
|
||||||
const QString ShowBordersModelNodes = "Show Model Nodes";
|
const QString ShowBordersModelNodes = "Show Model Nodes";
|
||||||
const QString ShowBordersParticleNodes = "Show Particle Nodes";
|
const QString ShowBordersParticleNodes = "Show Particle Nodes";
|
||||||
const QString ShowIKConstraints = "Show IK Constraints";
|
const QString ShowIKConstraints = "Show IK Constraints";
|
||||||
|
const QString StandOnNearbyFloors = "Stand on nearby floors";
|
||||||
const QString Stars = "Stars";
|
const QString Stars = "Stars";
|
||||||
const QString Stats = "Stats";
|
const QString Stats = "Stats";
|
||||||
const QString StopAllScripts = "Stop All Scripts";
|
const QString StopAllScripts = "Stop All Scripts";
|
||||||
|
|
|
@ -134,45 +134,7 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
_handState = HAND_STATE_NULL;
|
_handState = HAND_STATE_NULL;
|
||||||
|
|
||||||
updateOrientation(deltaTime);
|
updateOrientation(deltaTime);
|
||||||
|
updatePosition(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);
|
|
||||||
if (gravityLength > EPSILON) {
|
|
||||||
const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape();
|
|
||||||
glm::vec3 startCap;
|
|
||||||
boundingShape.getStartPoint(startCap);
|
|
||||||
glm::vec3 bottomOfBoundingCapsule = startCap + (boundingShape.getRadius() / gravityLength) * _gravity;
|
|
||||||
|
|
||||||
float fallThreshold = 2.0f * deltaTime * gravityLength;
|
|
||||||
walkingOnFloor = (glm::distance(bottomOfBoundingCapsule, _lastFloorContactPoint) < fallThreshold);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyboardInput > 0.0f || glm::length2(_velocity) > 0.0f || glm::length2(_thrust) > 0.0f ||
|
|
||||||
! walkingOnFloor) {
|
|
||||||
// apply gravity
|
|
||||||
_velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime);
|
|
||||||
|
|
||||||
// update motor and thrust
|
|
||||||
updateMotorFromKeyboard(deltaTime, walkingOnFloor);
|
|
||||||
applyMotor(deltaTime);
|
|
||||||
applyThrust(deltaTime);
|
|
||||||
|
|
||||||
// update position
|
|
||||||
if (glm::length2(_velocity) < EPSILON) {
|
|
||||||
_velocity = glm::vec3(0.0f);
|
|
||||||
} else {
|
|
||||||
_position += _velocity * deltaTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update moving flag based on speed
|
|
||||||
const float MOVING_SPEED_THRESHOLD = 0.01f;
|
|
||||||
_moving = glm::length(_velocity) > MOVING_SPEED_THRESHOLD;
|
|
||||||
updateChatCircle(deltaTime);
|
|
||||||
|
|
||||||
// update avatar skeleton and simulate hand and head
|
// update avatar skeleton and simulate hand and head
|
||||||
getHand()->collideAgainstOurself();
|
getHand()->collideAgainstOurself();
|
||||||
|
@ -206,19 +168,17 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
radius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cos(myCamera->getFieldOfView() / 2.0f));
|
radius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cos(myCamera->getFieldOfView() / 2.0f));
|
||||||
radius *= COLLISION_RADIUS_SCALAR;
|
radius *= COLLISION_RADIUS_SCALAR;
|
||||||
}
|
}
|
||||||
if (_collisionGroups) {
|
updateShapePositions();
|
||||||
updateShapePositions();
|
if (_collisionGroups & COLLISION_GROUP_ENVIRONMENT) {
|
||||||
if (_collisionGroups & COLLISION_GROUP_ENVIRONMENT) {
|
updateCollisionWithEnvironment(deltaTime, radius);
|
||||||
updateCollisionWithEnvironment(deltaTime, radius);
|
}
|
||||||
}
|
if (_collisionGroups & COLLISION_GROUP_VOXELS) {
|
||||||
if (_collisionGroups & COLLISION_GROUP_VOXELS) {
|
updateCollisionWithVoxels(deltaTime, radius);
|
||||||
updateCollisionWithVoxels(deltaTime, radius);
|
} else {
|
||||||
} else {
|
_trapDuration = 0.0f;
|
||||||
_trapDuration = 0.0f;
|
}
|
||||||
}
|
if (_collisionGroups & COLLISION_GROUP_AVATARS) {
|
||||||
if (_collisionGroups & COLLISION_GROUP_AVATARS) {
|
updateCollisionWithAvatars(deltaTime);
|
||||||
updateCollisionWithAvatars(deltaTime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,9 +383,9 @@ void MyAvatar::setGravity(const glm::vec3& gravity) {
|
||||||
float gravityLength = glm::length(gravity);
|
float gravityLength = glm::length(gravity);
|
||||||
if (gravityLength > EPSILON) {
|
if (gravityLength > EPSILON) {
|
||||||
_worldUpDirection = _gravity / -gravityLength;
|
_worldUpDirection = _gravity / -gravityLength;
|
||||||
} else {
|
|
||||||
_worldUpDirection = DEFAULT_UP_DIRECTION;
|
|
||||||
}
|
}
|
||||||
|
// NOTE: the else case here it to leave _worldUpDirection unchanged
|
||||||
|
// so it continues to point opposite to the previous gravity setting.
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationHandlePointer MyAvatar::addAnimationHandle() {
|
AnimationHandlePointer MyAvatar::addAnimationHandle() {
|
||||||
|
@ -890,8 +850,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
// We must adjust the body orientation using a delta rotation (rather than
|
// We must adjust the body orientation using a delta rotation (rather than
|
||||||
// doing yaw math) because the body's yaw ranges are not the same
|
// doing yaw math) because the body's yaw ranges are not the same
|
||||||
// as what the Oculus API provides.
|
// as what the Oculus API provides.
|
||||||
glm::vec3 UP_AXIS = glm::vec3(0.0f, 1.0f, 0.0f);
|
glm::quat bodyCorrection = glm::angleAxis(glm::radians(delta), _worldUpDirection);
|
||||||
glm::quat bodyCorrection = glm::angleAxis(glm::radians(delta), UP_AXIS);
|
|
||||||
orientation = orientation * bodyCorrection;
|
orientation = orientation * bodyCorrection;
|
||||||
}
|
}
|
||||||
Head* head = getHead();
|
Head* head = getHead();
|
||||||
|
@ -905,6 +864,89 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
setOrientation(orientation);
|
setOrientation(orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape();
|
||||||
|
glm::vec3 startCap;
|
||||||
|
boundingShape.getStartPoint(startCap);
|
||||||
|
glm::vec3 bottomOfBoundingCapsule = startCap - boundingShape.getRadius() * _worldUpDirection;
|
||||||
|
|
||||||
|
if (gravityLength > EPSILON) {
|
||||||
|
float speedFromGravity = _scale * deltaTime * gravityLength;
|
||||||
|
float distanceToFall = glm::distance(bottomOfBoundingCapsule, _lastFloorContactPoint);
|
||||||
|
walkingOnFloor = (distanceToFall < 2.0f * deltaTime * speedFromGravity);
|
||||||
|
|
||||||
|
if (walkingOnFloor) {
|
||||||
|
// 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 {
|
||||||
|
_velocity -= speedFromGravity * _worldUpDirection;
|
||||||
|
}
|
||||||
|
if (_motionBehaviors & AVATAR_MOTION_STAND_ON_NEARBY_FLOORS) {
|
||||||
|
const float MAX_VERTICAL_FLOOR_DETECTION_SPEED = _scale * MAX_WALKING_SPEED;
|
||||||
|
if (keyboardInput && glm::dot(_motorVelocity, _worldUpDirection) > 0.0f &&
|
||||||
|
glm::dot(_velocity, _worldUpDirection) > MAX_VERTICAL_FLOOR_DETECTION_SPEED) {
|
||||||
|
// disable gravity because we're pushing with keyboard
|
||||||
|
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
|
||||||
|
glm::vec3 direction = -_worldUpDirection;
|
||||||
|
OctreeElement* elementHit; // output from findRayIntersection
|
||||||
|
float distance; // output from findRayIntersection
|
||||||
|
BoxFace face; // output from findRayIntersection
|
||||||
|
Application::getInstance()->getVoxelTree()->findRayIntersection(bottomOfBoundingCapsule, direction, elementHit, distance, face);
|
||||||
|
const float NEARBY_FLOOR_THRESHOLD = _scale * 2.0f;
|
||||||
|
if (elementHit && distance < NEARBY_FLOOR_THRESHOLD) {
|
||||||
|
// turn on local gravity
|
||||||
|
setLocalGravity(-_worldUpDirection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyboardInput > 0.0f || glm::length2(_velocity) > 0.0f || glm::length2(_thrust) > 0.0f || ! walkingOnFloor) {
|
||||||
|
// update motor and thrust
|
||||||
|
updateMotorFromKeyboard(deltaTime, walkingOnFloor);
|
||||||
|
applyMotor(deltaTime);
|
||||||
|
applyThrust(deltaTime);
|
||||||
|
|
||||||
|
// update position
|
||||||
|
if (glm::length2(_velocity) < EPSILON) {
|
||||||
|
_velocity = glm::vec3(0.0f);
|
||||||
|
} else {
|
||||||
|
_position += _velocity * deltaTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update moving flag based on speed
|
||||||
|
const float MOVING_SPEED_THRESHOLD = 0.01f;
|
||||||
|
_moving = glm::length(_velocity) > MOVING_SPEED_THRESHOLD;
|
||||||
|
|
||||||
|
updateChatCircle(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
void MyAvatar::updateMotorFromKeyboard(float deltaTime, bool walking) {
|
void MyAvatar::updateMotorFromKeyboard(float deltaTime, bool walking) {
|
||||||
// Increase motor velocity until its length is equal to _maxMotorSpeed.
|
// Increase motor velocity until its length is equal to _maxMotorSpeed.
|
||||||
if (!(_motionBehaviors & AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED)) {
|
if (!(_motionBehaviors & AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED)) {
|
||||||
|
@ -930,12 +972,12 @@ void MyAvatar::updateMotorFromKeyboard(float deltaTime, bool walking) {
|
||||||
if (directionLength > EPSILON) {
|
if (directionLength > EPSILON) {
|
||||||
direction /= directionLength;
|
direction /= directionLength;
|
||||||
// the finalMotorSpeed depends on whether we are walking or not
|
// the finalMotorSpeed depends on whether we are walking or not
|
||||||
float finalMaxMotorSpeed = walking ? MAX_WALKING_SPEED : _maxMotorSpeed;
|
float finalMaxMotorSpeed = walking ? _scale * MAX_WALKING_SPEED : _scale * _maxMotorSpeed;
|
||||||
|
|
||||||
float motorLength = glm::length(_motorVelocity);
|
float motorLength = glm::length(_motorVelocity);
|
||||||
if (motorLength < 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 = MIN_KEYBOARD_CONTROL_SPEED * direction;
|
_motorVelocity = _scale * MIN_KEYBOARD_CONTROL_SPEED * direction;
|
||||||
} else {
|
} else {
|
||||||
float MOTOR_LENGTH_TIMESCALE = 1.5f;
|
float MOTOR_LENGTH_TIMESCALE = 1.5f;
|
||||||
float tau = glm::clamp(deltaTime / MOTOR_LENGTH_TIMESCALE, 0.0f, 1.0f);
|
float tau = glm::clamp(deltaTime / MOTOR_LENGTH_TIMESCALE, 0.0f, 1.0f);
|
||||||
|
@ -1178,6 +1220,8 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) {
|
||||||
const float MIN_STEP_HEIGHT = 0.0f;
|
const float MIN_STEP_HEIGHT = 0.0f;
|
||||||
glm::vec3 footBase = boundingShape.getPosition() - (capsuleRadius + capsuleHalfHeight) * _worldUpDirection;
|
glm::vec3 footBase = boundingShape.getPosition() - (capsuleRadius + capsuleHalfHeight) * _worldUpDirection;
|
||||||
float highestStep = 0.0f;
|
float highestStep = 0.0f;
|
||||||
|
float lowestStep = MAX_STEP_HEIGHT;
|
||||||
|
glm::vec3 floorPoint;
|
||||||
glm::vec3 stepPenetration(0.0f);
|
glm::vec3 stepPenetration(0.0f);
|
||||||
glm::vec3 totalPenetration(0.0f);
|
glm::vec3 totalPenetration(0.0f);
|
||||||
|
|
||||||
|
@ -1211,8 +1255,15 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) {
|
||||||
highestStep = stepHeight;
|
highestStep = stepHeight;
|
||||||
stepPenetration = collision->_penetration;
|
stepPenetration = collision->_penetration;
|
||||||
}
|
}
|
||||||
|
if (stepHeight < lowestStep) {
|
||||||
|
lowestStep = stepHeight;
|
||||||
|
floorPoint = collision->_contactPoint - collision->_penetration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (lowestStep < MAX_STEP_HEIGHT) {
|
||||||
|
_lastFloorContactPoint = floorPoint;
|
||||||
|
}
|
||||||
|
|
||||||
float penetrationLength = glm::length(totalPenetration);
|
float penetrationLength = glm::length(totalPenetration);
|
||||||
if (penetrationLength < EPSILON) {
|
if (penetrationLength < EPSILON) {
|
||||||
|
@ -1251,8 +1302,9 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) {
|
||||||
applyHardCollision(totalPenetration, VOXEL_ELASTICITY, VOXEL_DAMPING);
|
applyHardCollision(totalPenetration, VOXEL_ELASTICITY, VOXEL_DAMPING);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float VOXEL_COLLISION_FREQUENCY = 0.5f;
|
// Don't make a collision sound against voxlels by default -- too annoying when walking
|
||||||
updateCollisionSound(myCollisions[0]->_penetration, deltaTime, VOXEL_COLLISION_FREQUENCY);
|
//const float VOXEL_COLLISION_FREQUENCY = 0.5f;
|
||||||
|
//updateCollisionSound(myCollisions[0]->_penetration, deltaTime, VOXEL_COLLISION_FREQUENCY);
|
||||||
}
|
}
|
||||||
_trapDuration = isTrapped ? _trapDuration + deltaTime : 0.0f;
|
_trapDuration = isTrapped ? _trapDuration + deltaTime : 0.0f;
|
||||||
}
|
}
|
||||||
|
@ -1598,7 +1650,8 @@ void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::updateMotionBehaviorsFromMenu() {
|
void MyAvatar::updateMotionBehaviorsFromMenu() {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::ObeyEnvironmentalGravity)) {
|
Menu* menu = Menu::getInstance();
|
||||||
|
if (menu->isOptionChecked(MenuOption::ObeyEnvironmentalGravity)) {
|
||||||
_motionBehaviors |= AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY;
|
_motionBehaviors |= AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY;
|
||||||
// Environmental and Local gravities are incompatible. Environmental setting trumps local.
|
// Environmental and Local gravities are incompatible. Environmental setting trumps local.
|
||||||
_motionBehaviors &= ~AVATAR_MOTION_OBEY_LOCAL_GRAVITY;
|
_motionBehaviors &= ~AVATAR_MOTION_OBEY_LOCAL_GRAVITY;
|
||||||
|
@ -1608,6 +1661,14 @@ void MyAvatar::updateMotionBehaviorsFromMenu() {
|
||||||
if (! (_motionBehaviors & (AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY | AVATAR_MOTION_OBEY_LOCAL_GRAVITY))) {
|
if (! (_motionBehaviors & (AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY | AVATAR_MOTION_OBEY_LOCAL_GRAVITY))) {
|
||||||
setGravity(glm::vec3(0.0f));
|
setGravity(glm::vec3(0.0f));
|
||||||
}
|
}
|
||||||
|
if (menu->isOptionChecked(MenuOption::StandOnNearbyFloors)) {
|
||||||
|
_motionBehaviors |= AVATAR_MOTION_STAND_ON_NEARBY_FLOORS;
|
||||||
|
// standing on floors requires collision with voxels
|
||||||
|
_collisionGroups |= COLLISION_GROUP_VOXELS;
|
||||||
|
menu->setIsOptionChecked(MenuOption::CollideWithVoxels, true);
|
||||||
|
} else {
|
||||||
|
_motionBehaviors &= ~AVATAR_MOTION_STAND_ON_NEARBY_FLOORS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::renderAttachments(RenderMode renderMode) {
|
void MyAvatar::renderAttachments(RenderMode renderMode) {
|
||||||
|
@ -1634,6 +1695,11 @@ void MyAvatar::setCollisionGroups(quint32 collisionGroups) {
|
||||||
menu->setIsOptionChecked(MenuOption::CollideWithAvatars, (bool)(_collisionGroups & COLLISION_GROUP_AVATARS));
|
menu->setIsOptionChecked(MenuOption::CollideWithAvatars, (bool)(_collisionGroups & COLLISION_GROUP_AVATARS));
|
||||||
menu->setIsOptionChecked(MenuOption::CollideWithVoxels, (bool)(_collisionGroups & COLLISION_GROUP_VOXELS));
|
menu->setIsOptionChecked(MenuOption::CollideWithVoxels, (bool)(_collisionGroups & COLLISION_GROUP_VOXELS));
|
||||||
menu->setIsOptionChecked(MenuOption::CollideWithParticles, (bool)(_collisionGroups & COLLISION_GROUP_PARTICLES));
|
menu->setIsOptionChecked(MenuOption::CollideWithParticles, (bool)(_collisionGroups & COLLISION_GROUP_PARTICLES));
|
||||||
|
if (! (_collisionGroups & COLLISION_GROUP_VOXELS)) {
|
||||||
|
// no collision with voxels --> disable standing on floors
|
||||||
|
_motionBehaviors &= ~AVATAR_MOTION_STAND_ON_NEARBY_FLOORS;
|
||||||
|
menu->setIsOptionChecked(MenuOption::StandOnNearbyFloors, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::setMotionBehaviorsByScript(quint32 flags) {
|
void MyAvatar::setMotionBehaviorsByScript(quint32 flags) {
|
||||||
|
|
|
@ -150,7 +150,6 @@ private:
|
||||||
bool _shouldJump;
|
bool _shouldJump;
|
||||||
float _driveKeys[MAX_DRIVE_KEYS];
|
float _driveKeys[MAX_DRIVE_KEYS];
|
||||||
glm::vec3 _gravity;
|
glm::vec3 _gravity;
|
||||||
glm::vec3 _environmentGravity;
|
|
||||||
float _distanceToNearestAvatar; // How close is the nearest avatar?
|
float _distanceToNearestAvatar; // How close is the nearest avatar?
|
||||||
|
|
||||||
bool _wasPushing;
|
bool _wasPushing;
|
||||||
|
@ -175,6 +174,7 @@ private:
|
||||||
|
|
||||||
// private methods
|
// private methods
|
||||||
void updateOrientation(float deltaTime);
|
void updateOrientation(float deltaTime);
|
||||||
|
void updatePosition(float deltaTime);
|
||||||
void updateMotorFromKeyboard(float deltaTime, bool walking);
|
void updateMotorFromKeyboard(float deltaTime, bool walking);
|
||||||
float computeMotorTimescale();
|
float computeMotorTimescale();
|
||||||
void applyMotor(float deltaTime);
|
void applyMotor(float deltaTime);
|
||||||
|
|
|
@ -53,23 +53,27 @@ 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_ENABLED = 1U << 0;
|
||||||
const quint32 AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED = 1U << 1;
|
const quint32 AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED = 1U << 1;
|
||||||
const quint32 AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME = 1U << 2;
|
const quint32 AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME = 1U << 2;
|
||||||
const quint32 AVATAR_MOTION_MOTOR_COLLISION_SURFACE_ONLY = 1U << 3;
|
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 << 4;
|
||||||
const quint32 AVATAR_MOTION_OBEY_LOCAL_GRAVITY = 1U << 5;
|
const quint32 AVATAR_MOTION_OBEY_LOCAL_GRAVITY = 1U << 5;
|
||||||
|
|
||||||
|
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_ENABLED |
|
||||||
AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED |
|
AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED |
|
||||||
AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME;
|
AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME |
|
||||||
|
AVATAR_MOTION_STAND_ON_NEARBY_FLOORS;
|
||||||
|
|
||||||
// these bits will be expanded as features are exposed
|
// these bits will be expanded as features are exposed
|
||||||
const quint32 AVATAR_MOTION_SCRIPTABLE_BITS =
|
const quint32 AVATAR_MOTION_SCRIPTABLE_BITS =
|
||||||
AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY |
|
AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY |
|
||||||
AVATAR_MOTION_OBEY_LOCAL_GRAVITY;
|
AVATAR_MOTION_OBEY_LOCAL_GRAVITY |
|
||||||
|
AVATAR_MOTION_STAND_ON_NEARBY_FLOORS;
|
||||||
|
|
||||||
|
|
||||||
// First bitset
|
// First bitset
|
||||||
|
|
|
@ -98,7 +98,7 @@ void AccountManager::updateBalance() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountManager::accountInfoBalanceChanged(quint64 newBalance) {
|
void AccountManager::accountInfoBalanceChanged(qint64 newBalance) {
|
||||||
emit balanceChanged(newBalance);
|
emit balanceChanged(newBalance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ public slots:
|
||||||
void requestError(QNetworkReply::NetworkError error);
|
void requestError(QNetworkReply::NetworkError error);
|
||||||
void logout();
|
void logout();
|
||||||
void updateBalance();
|
void updateBalance();
|
||||||
void accountInfoBalanceChanged(quint64 newBalance);
|
void accountInfoBalanceChanged(qint64 newBalance);
|
||||||
signals:
|
signals:
|
||||||
void authRequired();
|
void authRequired();
|
||||||
void authEndpointChanged();
|
void authEndpointChanged();
|
||||||
|
@ -73,7 +73,7 @@ signals:
|
||||||
void loginComplete(const QUrl& authURL);
|
void loginComplete(const QUrl& authURL);
|
||||||
void loginFailed();
|
void loginFailed();
|
||||||
void logoutComplete();
|
void logoutComplete();
|
||||||
void balanceChanged(quint64 newBalance);
|
void balanceChanged(qint64 newBalance);
|
||||||
private slots:
|
private slots:
|
||||||
void processReply();
|
void processReply();
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -83,7 +83,7 @@ void DataServerAccountInfo::setDiscourseApiKey(const QString& discourseApiKey) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataServerAccountInfo::setBalance(quint64 balance) {
|
void DataServerAccountInfo::setBalance(qint64 balance) {
|
||||||
if (!_hasBalance || _balance != balance) {
|
if (!_hasBalance || _balance != balance) {
|
||||||
_balance = balance;
|
_balance = balance;
|
||||||
_hasBalance = true;
|
_hasBalance = true;
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include "OAuthAccessToken.h"
|
#include "OAuthAccessToken.h"
|
||||||
|
|
||||||
|
const float SATOSHIS_PER_CREDIT = 10.0e8f;
|
||||||
|
|
||||||
class DataServerAccountInfo : public QObject {
|
class DataServerAccountInfo : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -35,8 +37,8 @@ public:
|
||||||
const QString& getDiscourseApiKey() const { return _discourseApiKey; }
|
const QString& getDiscourseApiKey() const { return _discourseApiKey; }
|
||||||
void setDiscourseApiKey(const QString& discourseApiKey);
|
void setDiscourseApiKey(const QString& discourseApiKey);
|
||||||
|
|
||||||
quint64 getBalance() const { return _balance; }
|
qint64 getBalance() const { return _balance; }
|
||||||
void setBalance(quint64 balance);
|
void setBalance(qint64 balance);
|
||||||
bool hasBalance() const { return _hasBalance; }
|
bool hasBalance() const { return _hasBalance; }
|
||||||
void setHasBalance(bool hasBalance) { _hasBalance = hasBalance; }
|
void setHasBalance(bool hasBalance) { _hasBalance = hasBalance; }
|
||||||
Q_INVOKABLE void setBalanceFromJSON(const QJsonObject& jsonObject);
|
Q_INVOKABLE void setBalanceFromJSON(const QJsonObject& jsonObject);
|
||||||
|
@ -44,7 +46,7 @@ public:
|
||||||
friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info);
|
friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info);
|
||||||
friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info);
|
friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info);
|
||||||
signals:
|
signals:
|
||||||
quint64 balanceChanged(quint64 newBalance);
|
qint64 balanceChanged(qint64 newBalance);
|
||||||
private:
|
private:
|
||||||
void swap(DataServerAccountInfo& otherInfo);
|
void swap(DataServerAccountInfo& otherInfo);
|
||||||
|
|
||||||
|
@ -52,7 +54,7 @@ private:
|
||||||
QString _username;
|
QString _username;
|
||||||
QString _xmppPassword;
|
QString _xmppPassword;
|
||||||
QString _discourseApiKey;
|
QString _discourseApiKey;
|
||||||
quint64 _balance;
|
qint64 _balance;
|
||||||
bool _hasBalance;
|
bool _hasBalance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue