mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 20:44:14 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into 19418
This commit is contained in:
commit
681a72746e
16 changed files with 126 additions and 74 deletions
|
@ -3850,7 +3850,7 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
|||
if (!avatar->isInitialized()) {
|
||||
avatar->init();
|
||||
}
|
||||
avatar->render(false, Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls));
|
||||
avatar->render(false);
|
||||
avatar->setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors));
|
||||
}
|
||||
|
||||
|
@ -3860,12 +3860,12 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
|||
// render avatar fades
|
||||
Glower glower;
|
||||
for (vector<Avatar*>::iterator fade = _avatarFades.begin(); fade != _avatarFades.end(); fade++) {
|
||||
(*fade)->render(false, Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls));
|
||||
(*fade)->render(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Render my own Avatar
|
||||
_myAvatar.render(forceRenderHead, Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls));
|
||||
_myAvatar.render(forceRenderHead);
|
||||
_myAvatar.setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors));
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::LookAtIndicator) && _lookatTargetAvatar) {
|
||||
|
|
|
@ -27,12 +27,8 @@
|
|||
#include "Menu.h"
|
||||
#include "Util.h"
|
||||
|
||||
// Uncomment the following definition to test audio device latency by copying output to input
|
||||
//#define TEST_AUDIO_LOOPBACK
|
||||
//#define SHOW_AUDIO_DEBUG
|
||||
|
||||
#define VISUALIZE_ECHO_CANCELLATION
|
||||
|
||||
static const int PHASE_DELAY_AT_90 = 20;
|
||||
static const float AMPLITUDE_RATIO_AT_90 = 0.5;
|
||||
static const int MIN_FLANGE_EFFECT_THRESHOLD = 600;
|
||||
|
@ -84,11 +80,17 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o
|
|||
memset(outputLeft, 0, PACKET_LENGTH_BYTES_PER_CHANNEL);
|
||||
memset(outputRight, 0, PACKET_LENGTH_BYTES_PER_CHANNEL);
|
||||
|
||||
// If Mute button is pressed, clear the input buffer
|
||||
// If Mute button is pressed, clear the input buffer
|
||||
if (_muted) {
|
||||
memset(inputLeft, 0, PACKET_LENGTH_BYTES_PER_CHANNEL);
|
||||
}
|
||||
|
||||
// If local loopback enabled, copy input to output
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::EchoLocalAudio)) {
|
||||
memcpy(outputLeft, inputLeft, PACKET_LENGTH_BYTES_PER_CHANNEL);
|
||||
memcpy(outputRight, inputLeft, PACKET_LENGTH_BYTES_PER_CHANNEL);
|
||||
}
|
||||
|
||||
// Add Procedural effects to input samples
|
||||
addProceduralSounds(inputLeft, outputLeft, outputRight, BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||
|
||||
|
@ -120,7 +122,7 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o
|
|||
// + 12 for 3 floats for position + float for bearing + 1 attenuation byte
|
||||
unsigned char dataPacket[MAX_PACKET_SIZE];
|
||||
|
||||
PACKET_TYPE packetType = Menu::getInstance()->isOptionChecked(MenuOption::EchoAudio)
|
||||
PACKET_TYPE packetType = Menu::getInstance()->isOptionChecked(MenuOption::EchoServerAudio)
|
||||
? PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO
|
||||
: PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO;
|
||||
|
||||
|
@ -360,7 +362,8 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) :
|
|||
_collisionSoundDuration(0.0f),
|
||||
_proceduralEffectSample(0),
|
||||
_heartbeatMagnitude(0.0f),
|
||||
_muted(false)
|
||||
_muted(false),
|
||||
_localEcho(false)
|
||||
{
|
||||
outputPortAudioError(Pa_Initialize());
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
// in which case 'true' is returned - otherwise the return value is 'false'.
|
||||
// The results of the analysis are written to the log.
|
||||
bool eventuallyAnalyzePing();
|
||||
|
||||
private:
|
||||
|
||||
PaStream* _stream;
|
||||
|
@ -109,6 +110,7 @@ private:
|
|||
float _heartbeatMagnitude;
|
||||
|
||||
bool _muted;
|
||||
bool _localEcho;
|
||||
GLuint _micTextureId;
|
||||
GLuint _muteTextureId;
|
||||
QRect _iconBounds;
|
||||
|
|
|
@ -36,11 +36,18 @@
|
|||
Menu* Menu::_instance = NULL;
|
||||
|
||||
Menu* Menu::getInstance() {
|
||||
static QMutex menuInstanceMutex;
|
||||
|
||||
// lock the menu instance mutex to make sure we don't race and create two menus and crash
|
||||
menuInstanceMutex.lock();
|
||||
|
||||
if (!_instance) {
|
||||
qDebug("First call to Menu::getInstance() - initing menu.\n");
|
||||
|
||||
_instance = new Menu();
|
||||
}
|
||||
|
||||
menuInstanceMutex.unlock();
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
@ -484,8 +491,9 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P);
|
||||
|
||||
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
|
||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoAudio);
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio);
|
||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio);
|
||||
|
||||
QMenu* voxelProtoOptionsMenu = developerMenu->addMenu("Voxel Server Protocol Options");
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::SendVoxelColors);
|
||||
|
|
|
@ -168,7 +168,8 @@ namespace MenuOption {
|
|||
const QString DisplayLeapHands = "Display Leap Hands";
|
||||
const QString DontRenderVoxels = "Don't call _voxels.render()";
|
||||
const QString DontCallOpenGLForVoxels = "Don't call glDrawRangeElementsEXT() for Voxels";
|
||||
const QString EchoAudio = "Echo Audio";
|
||||
const QString EchoServerAudio = "Echo Server Audio";
|
||||
const QString EchoLocalAudio = "Echo Local Audio";
|
||||
const QString ExportVoxels = "Export Voxels";
|
||||
const QString ExtraDebugging = "Extra Debugging";
|
||||
const QString DontFadeOnVoxelServerChanges = "Don't Fade In/Out on Voxel Server Changes";
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "DataServerClient.h"
|
||||
#include "Hand.h"
|
||||
#include "Head.h"
|
||||
#include "Menu.h"
|
||||
#include "Physics.h"
|
||||
#include "world.h"
|
||||
#include "devices/OculusManager.h"
|
||||
|
@ -394,7 +395,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
_skeletonModel.simulate(deltaTime);
|
||||
_head.setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
|
||||
glm::vec3 headPosition;
|
||||
if (!_skeletonModel.getHeadPosition(headPosition)) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls) || !_skeletonModel.getHeadPosition(headPosition)) {
|
||||
headPosition = _bodyBall[BODY_BALL_HEAD_BASE].position;
|
||||
}
|
||||
_head.setPosition(headPosition);
|
||||
|
@ -439,7 +440,7 @@ static TextRenderer* textRenderer() {
|
|||
return renderer;
|
||||
}
|
||||
|
||||
void Avatar::render(bool forceRenderHead, bool renderAvatarBalls) {
|
||||
void Avatar::render(bool forceRenderHead) {
|
||||
|
||||
if (Application::getInstance()->getAvatar()->getHand().isRaveGloveActive()) {
|
||||
_hand.setRaveLights(RAVE_LIGHTS_AVATAR);
|
||||
|
@ -455,7 +456,7 @@ void Avatar::render(bool forceRenderHead, bool renderAvatarBalls) {
|
|||
Glower glower(_moving && glm::length(toTarget) > GLOW_DISTANCE ? 1.0f : 0.0f);
|
||||
|
||||
// render body
|
||||
renderBody(forceRenderHead, renderAvatarBalls);
|
||||
renderBody(forceRenderHead);
|
||||
|
||||
// render sphere when far away
|
||||
const float MAX_ANGLE = 10.f;
|
||||
|
@ -666,7 +667,8 @@ void Avatar::updateArmIKAndConstraints(float deltaTime, AvatarJointID fingerTipJ
|
|||
float distance = glm::length(armVector);
|
||||
|
||||
// don't let right hand get dragged beyond maximum arm length...
|
||||
float armLength = _skeletonModel.isActive() ? _skeletonModel.getRightArmLength() : _skeleton.getArmLength();
|
||||
float armLength = (_skeletonModel.isActive() && !Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls)) ?
|
||||
_skeletonModel.getRightArmLength() : _skeleton.getArmLength();
|
||||
const float ARM_RETRACTION = 0.75f;
|
||||
float retractedArmLength = armLength * ARM_RETRACTION;
|
||||
if (distance > retractedArmLength) {
|
||||
|
@ -713,7 +715,7 @@ float Avatar::getBallRenderAlpha(int ball, bool forceRenderHead) const {
|
|||
return 1.0f;
|
||||
}
|
||||
|
||||
void Avatar::renderBody(bool forceRenderHead, bool renderAvatarBalls) {
|
||||
void Avatar::renderBody(bool forceRenderHead) {
|
||||
|
||||
if (_head.getVideoFace().isFullFrame()) {
|
||||
// Render the full-frame video
|
||||
|
@ -721,7 +723,7 @@ void Avatar::renderBody(bool forceRenderHead, bool renderAvatarBalls) {
|
|||
if (alpha > 0.0f) {
|
||||
_head.getVideoFace().render(1.0f);
|
||||
}
|
||||
} else if (renderAvatarBalls || !(_voxels.getVoxelURL().isValid() || _skeletonModel.isActive())) {
|
||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls)) {
|
||||
// Render the body as balls and cones
|
||||
glm::vec3 skinColor, darkSkinColor;
|
||||
getSkinColors(skinColor, darkSkinColor);
|
||||
|
@ -738,7 +740,7 @@ void Avatar::renderBody(bool forceRenderHead, bool renderAvatarBalls) {
|
|||
// Always render other people, and render myself when beyond threshold distance
|
||||
if (b == BODY_BALL_HEAD_BASE) { // the head is rendered as a special
|
||||
if (alpha > 0.0f) {
|
||||
_head.render(alpha, false);
|
||||
_head.render(alpha, true);
|
||||
}
|
||||
} else if (alpha > 0.0f) {
|
||||
// Render the body ball sphere
|
||||
|
@ -746,10 +748,6 @@ void Avatar::renderBody(bool forceRenderHead, bool renderAvatarBalls) {
|
|||
skinColor.g - _bodyBall[b].touchForce * 0.2f,
|
||||
skinColor.b - _bodyBall[b].touchForce * 0.1f);
|
||||
|
||||
if (b == BODY_BALL_NECK_BASE && _head.getFaceModel().isActive()) {
|
||||
continue; // don't render the neck if we have a face model
|
||||
}
|
||||
|
||||
if ((b != BODY_BALL_HEAD_TOP )
|
||||
&& (b != BODY_BALL_HEAD_BASE )) {
|
||||
glPushMatrix();
|
||||
|
@ -793,7 +791,7 @@ void Avatar::renderBody(bool forceRenderHead, bool renderAvatarBalls) {
|
|||
void Avatar::getSkinColors(glm::vec3& lighter, glm::vec3& darker) {
|
||||
lighter = glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]);
|
||||
darker = glm::vec3(DARK_SKIN_COLOR[0], DARK_SKIN_COLOR[1], DARK_SKIN_COLOR[2]);
|
||||
if (_head.getFaceModel().isActive()) {
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls) && _head.getFaceModel().isActive()) {
|
||||
lighter = glm::vec3(_head.getFaceModel().computeAverageColor());
|
||||
const float SKIN_DARKENING = 0.9f;
|
||||
darker = lighter * SKIN_DARKENING;
|
||||
|
|
|
@ -141,7 +141,7 @@ public:
|
|||
void init();
|
||||
void simulate(float deltaTime, Transmitter* transmitter);
|
||||
void follow(Avatar* leadingAvatar);
|
||||
void render(bool forceRenderHead, bool renderAvatarBalls);
|
||||
void render(bool forceRenderHead);
|
||||
|
||||
//setters
|
||||
void setDisplayingLookatVectors(bool displayingLookatVectors) { _head.setRenderLookatVectors(displayingLookatVectors); }
|
||||
|
@ -256,7 +256,7 @@ private:
|
|||
// private methods...
|
||||
glm::vec3 calculateAverageEyePosition() { return _head.calculateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat)
|
||||
float getBallRenderAlpha(int ball, bool forceRenderHead) const;
|
||||
void renderBody(bool forceRenderHead, bool renderAvatarBalls);
|
||||
void renderBody(bool forceRenderHead);
|
||||
void initializeBodyBalls();
|
||||
void resetBodyBalls();
|
||||
void updateHandMovementAndTouching(float deltaTime, bool enableHandMovement);
|
||||
|
|
|
@ -250,7 +250,9 @@ void Head::simulate(float deltaTime, bool isMine) {
|
|||
calculateGeometry();
|
||||
|
||||
// the blend face may have custom eye meshes
|
||||
_faceModel.getEyePositions(_leftEyePosition, _rightEyePosition);
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls)) {
|
||||
_faceModel.getEyePositions(_leftEyePosition, _rightEyePosition);
|
||||
}
|
||||
}
|
||||
|
||||
void Head::calculateGeometry() {
|
||||
|
@ -295,10 +297,11 @@ void Head::calculateGeometry() {
|
|||
+ up * _scale * NOSE_UPTURN;
|
||||
}
|
||||
|
||||
void Head::render(float alpha, bool isMine) {
|
||||
void Head::render(float alpha, bool renderAvatarBalls) {
|
||||
_renderAlpha = alpha;
|
||||
|
||||
if (!(_videoFace.render(alpha) || _faceModel.render(alpha))) {
|
||||
bool lookatVectorsVisible = _renderLookatVectors;
|
||||
if (renderAvatarBalls) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_RESCALE_NORMAL);
|
||||
|
||||
|
@ -309,9 +312,12 @@ void Head::render(float alpha, bool isMine) {
|
|||
renderMouth();
|
||||
renderNose();
|
||||
renderEyeBrows();
|
||||
|
||||
} else if (!_videoFace.render(alpha)) {
|
||||
lookatVectorsVisible &= _faceModel.render(alpha);
|
||||
}
|
||||
|
||||
if (_renderLookatVectors) {
|
||||
|
||||
if (lookatVectorsVisible) {
|
||||
renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
void init();
|
||||
void reset();
|
||||
void simulate(float deltaTime, bool isMine);
|
||||
void render(float alpha, bool isMine);
|
||||
void render(float alpha, bool renderAvatarBalls);
|
||||
void renderMohawk();
|
||||
|
||||
void setScale(float scale);
|
||||
|
|
|
@ -325,7 +325,7 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
_skeletonModel.simulate(deltaTime);
|
||||
_head.setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
|
||||
glm::vec3 headPosition;
|
||||
if (!_skeletonModel.getHeadPosition(headPosition)) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls) || !_skeletonModel.getHeadPosition(headPosition)) {
|
||||
headPosition = _bodyBall[BODY_BALL_HEAD_BASE].position;
|
||||
}
|
||||
_head.setPosition(headPosition);
|
||||
|
@ -381,15 +381,18 @@ void MyAvatar::updateFromGyrosAndOrWebcam(bool turnWithHead) {
|
|||
if (faceshift->isActive()) {
|
||||
estimatedPosition = faceshift->getHeadTranslation();
|
||||
estimatedRotation = safeEulerAngles(faceshift->getHeadRotation());
|
||||
// Rotate the body if the head is turned quickly
|
||||
// Rotate the body if the head is turned beyond the screen
|
||||
if (turnWithHead) {
|
||||
glm::vec3 headAngularVelocity = faceshift->getHeadAngularVelocity();
|
||||
const float FACESHIFT_YAW_TURN_SENSITIVITY = 0.25f;
|
||||
const float FACESHIFT_MIN_YAW_TURN = 10.f;
|
||||
const float FACESHIFT_MAX_YAW_TURN = 30.f;
|
||||
const float FACESHIFT_YAW_TURN_SENSITIVITY = 0.5f;
|
||||
const float FACESHIFT_MIN_YAW_TURN = 15.f;
|
||||
const float FACESHIFT_MAX_YAW_TURN = 50.f;
|
||||
if ( (fabs(estimatedRotation.y) > FACESHIFT_MIN_YAW_TURN) &&
|
||||
(fabs(estimatedRotation.y) < FACESHIFT_MAX_YAW_TURN) ) {
|
||||
_bodyYawDelta += estimatedRotation.y * FACESHIFT_YAW_TURN_SENSITIVITY;
|
||||
if (estimatedRotation.y > 0.f) {
|
||||
_bodyYawDelta += (estimatedRotation.y - FACESHIFT_MIN_YAW_TURN) * FACESHIFT_YAW_TURN_SENSITIVITY;
|
||||
} else {
|
||||
_bodyYawDelta += (estimatedRotation.y + FACESHIFT_MIN_YAW_TURN) * FACESHIFT_YAW_TURN_SENSITIVITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (gyros->isActive()) {
|
||||
|
@ -459,22 +462,33 @@ void MyAvatar::updateFromGyrosAndOrWebcam(bool turnWithHead) {
|
|||
if (!Menu::getInstance()->isOptionChecked(MenuOption::MoveWithLean)) {
|
||||
return;
|
||||
}
|
||||
const float ANGULAR_DRIVE_SCALE = 0.1f;
|
||||
const float ANGULAR_DEAD_ZONE = 0.3f;
|
||||
setDriveKeys(FWD, glm::clamp(-_head.getLeanForward() * ANGULAR_DRIVE_SCALE - ANGULAR_DEAD_ZONE, 0.0f, 1.0f));
|
||||
setDriveKeys(BACK, glm::clamp(_head.getLeanForward() * ANGULAR_DRIVE_SCALE - ANGULAR_DEAD_ZONE, 0.0f, 1.0f));
|
||||
setDriveKeys(LEFT, glm::clamp(_head.getLeanSideways() * ANGULAR_DRIVE_SCALE - ANGULAR_DEAD_ZONE, 0.0f, 1.0f));
|
||||
setDriveKeys(RIGHT, glm::clamp(-_head.getLeanSideways() * ANGULAR_DRIVE_SCALE - ANGULAR_DEAD_ZONE, 0.0f, 1.0f));
|
||||
|
||||
// only consider going up if we're not going in any of the four horizontal directions
|
||||
if (_driveKeys[FWD] == 0.0f && _driveKeys[BACK] == 0.0f && _driveKeys[LEFT] == 0.0f && _driveKeys[RIGHT] == 0.0f) {
|
||||
const float LINEAR_DRIVE_SCALE = 5.0f;
|
||||
const float LINEAR_DEAD_ZONE = 0.95f;
|
||||
float torsoDelta = glm::length(relativePosition) - TORSO_LENGTH;
|
||||
setDriveKeys(UP, glm::clamp(torsoDelta * LINEAR_DRIVE_SCALE - LINEAR_DEAD_ZONE, 0.0f, 1.0f));
|
||||
|
||||
} else {
|
||||
setDriveKeys(UP, 0.0f);
|
||||
// Move with Lean by applying thrust proportional to leaning
|
||||
glm::quat orientation = _head.getCameraOrientation();
|
||||
glm::vec3 front = orientation * IDENTITY_FRONT;
|
||||
glm::vec3 right = orientation * IDENTITY_RIGHT;
|
||||
float leanForward = _head.getLeanForward();
|
||||
float leanSideways = _head.getLeanSideways();
|
||||
|
||||
// Degrees of 'dead zone' when leaning, and amount of acceleration to apply to lean angle
|
||||
const float LEAN_FWD_DEAD_ZONE = 15.f;
|
||||
const float LEAN_SIDEWAYS_DEAD_ZONE = 10.f;
|
||||
const float LEAN_FWD_THRUST_SCALE = 4.f;
|
||||
const float LEAN_SIDEWAYS_THRUST_SCALE = 3.f;
|
||||
|
||||
if (fabs(leanForward) > LEAN_FWD_DEAD_ZONE) {
|
||||
if (leanForward > 0.f) {
|
||||
addThrust(front * -(leanForward - LEAN_FWD_DEAD_ZONE) * LEAN_FWD_THRUST_SCALE);
|
||||
} else {
|
||||
addThrust(front * -(leanForward + LEAN_FWD_DEAD_ZONE) * LEAN_FWD_THRUST_SCALE);
|
||||
}
|
||||
}
|
||||
if (fabs(leanSideways) > LEAN_SIDEWAYS_DEAD_ZONE) {
|
||||
if (leanSideways > 0.f) {
|
||||
addThrust(right * -(leanSideways - LEAN_SIDEWAYS_DEAD_ZONE) * LEAN_SIDEWAYS_THRUST_SCALE);
|
||||
} else {
|
||||
addThrust(right * -(leanSideways + LEAN_SIDEWAYS_DEAD_ZONE) * LEAN_SIDEWAYS_THRUST_SCALE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,7 +497,7 @@ static TextRenderer* textRenderer() {
|
|||
return renderer;
|
||||
}
|
||||
|
||||
void MyAvatar::render(bool forceRenderHead, bool renderAvatarBalls) {
|
||||
void MyAvatar::render(bool forceRenderHead) {
|
||||
|
||||
if (Application::getInstance()->getAvatar()->getHand().isRaveGloveActive()) {
|
||||
_hand.setRaveLights(RAVE_LIGHTS_AVATAR);
|
||||
|
@ -493,7 +507,7 @@ void MyAvatar::render(bool forceRenderHead, bool renderAvatarBalls) {
|
|||
renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f), _scale * 0.1f, 0.2f);
|
||||
|
||||
// render body
|
||||
renderBody(forceRenderHead, renderAvatarBalls);
|
||||
renderBody(forceRenderHead);
|
||||
|
||||
// if this is my avatar, then render my interactions with the other avatar
|
||||
_avatarTouch.render(Application::getInstance()->getCamera()->getPosition());
|
||||
|
@ -634,7 +648,7 @@ float MyAvatar::getBallRenderAlpha(int ball, bool forceRenderHead) const {
|
|||
(distanceToCamera - DO_NOT_RENDER_INSIDE) / (RENDER_OPAQUE_OUTSIDE - DO_NOT_RENDER_INSIDE), 0.f, 1.f);
|
||||
}
|
||||
|
||||
void MyAvatar::renderBody(bool forceRenderHead, bool renderAvatarBalls) {
|
||||
void MyAvatar::renderBody(bool forceRenderHead) {
|
||||
|
||||
if (_head.getVideoFace().isFullFrame()) {
|
||||
// Render the full-frame video
|
||||
|
@ -642,7 +656,7 @@ void MyAvatar::renderBody(bool forceRenderHead, bool renderAvatarBalls) {
|
|||
if (alpha > 0.0f) {
|
||||
_head.getVideoFace().render(1.0f);
|
||||
}
|
||||
} else if (renderAvatarBalls || !(_voxels.getVoxelURL().isValid() || _skeletonModel.isActive())) {
|
||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls)) {
|
||||
// Render the body as balls and cones
|
||||
glm::vec3 skinColor, darkSkinColor;
|
||||
getSkinColors(skinColor, darkSkinColor);
|
||||
|
@ -676,10 +690,6 @@ void MyAvatar::renderBody(bool forceRenderHead, bool renderAvatarBalls) {
|
|||
alpha);
|
||||
}
|
||||
|
||||
if (b == BODY_BALL_NECK_BASE && _head.getFaceModel().isActive()) {
|
||||
continue; // don't render the neck if we have a face model
|
||||
}
|
||||
|
||||
if ((b != BODY_BALL_HEAD_TOP )
|
||||
&& (b != BODY_BALL_HEAD_BASE )) {
|
||||
glPushMatrix();
|
||||
|
@ -715,7 +725,7 @@ void MyAvatar::renderBody(bool forceRenderHead, bool renderAvatarBalls) {
|
|||
}
|
||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, forceRenderHead);
|
||||
if (alpha > 0.0f) {
|
||||
_head.render(alpha, true);
|
||||
_head.render(alpha, false);
|
||||
}
|
||||
}
|
||||
_hand.render();
|
||||
|
@ -1147,17 +1157,20 @@ bool operator<(const SortedAvatar& s1, const SortedAvatar& s2) {
|
|||
}
|
||||
|
||||
void MyAvatar::updateChatCircle(float deltaTime) {
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::ChatCircling)) {
|
||||
if (!(_isChatCirclingEnabled = Menu::getInstance()->isOptionChecked(MenuOption::ChatCircling))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// find all members and sort by distance
|
||||
// find all circle-enabled members and sort by distance
|
||||
QVector<SortedAvatar> sortedAvatars;
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
||||
SortedAvatar sortedAvatar;
|
||||
sortedAvatar.avatar = (Avatar*)node->getLinkedData();
|
||||
if (!sortedAvatar.avatar->isChatCirclingEnabled()) {
|
||||
continue;
|
||||
}
|
||||
sortedAvatar.distance = glm::distance(_position, sortedAvatar.avatar->getPosition());
|
||||
sortedAvatars.append(sortedAvatar);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
void reset();
|
||||
void simulate(float deltaTime, Transmitter* transmitter);
|
||||
void updateFromGyrosAndOrWebcam(bool turnWithHead);
|
||||
void render(bool forceRenderHead, bool renderAvatarBalls);
|
||||
void render(bool forceRenderHead);
|
||||
void renderScreenTint(ScreenTintLayer layer);
|
||||
|
||||
// setters
|
||||
|
@ -82,7 +82,7 @@ private:
|
|||
|
||||
// private methods
|
||||
float getBallRenderAlpha(int ball, bool forceRenderHead) const;
|
||||
void renderBody(bool forceRenderHead, bool renderAvatarBalls);
|
||||
void renderBody(bool forceRenderHead);
|
||||
void updateThrust(float deltaTime, Transmitter * transmitter);
|
||||
void updateHandMovementAndTouching(float deltaTime, bool enableHandMovement);
|
||||
void updateAvatarCollisions(float deltaTime);
|
||||
|
|
|
@ -23,6 +23,8 @@ Profile::Profile(const QString &username) :
|
|||
if (!_username.isEmpty()) {
|
||||
// we've been given a new username, ask the data-server for profile
|
||||
DataServerClient::getClientValueForKey(DataServerKey::UUID);
|
||||
DataServerClient::getClientValueForKey(DataServerKey::FaceMeshURL);
|
||||
DataServerClient::getClientValueForKey(DataServerKey::SkeletonURL);
|
||||
|
||||
// send our current domain server to the data-server
|
||||
updateDomain(NodeList::getInstance()->getDomainHostname());
|
||||
|
|
|
@ -58,12 +58,20 @@ void SixenseManager::update() {
|
|||
avatar->setDriveKeys(DOWN, data.trigger);
|
||||
}
|
||||
|
||||
// set palm position and normal based on Hydra position/orientation
|
||||
// Set palm position and normal based on Hydra position/orientation
|
||||
PalmData palm(&hand);
|
||||
palm.setActive(true);
|
||||
glm::vec3 position(-data.pos[0], data.pos[1], -data.pos[2]);
|
||||
glm::vec3 position(data.pos[0], data.pos[1], data.pos[2]);
|
||||
|
||||
// Adjust for distance between acquisition 'orb' and the user's torso
|
||||
// (distance to the right of body center, distance below torso, distance behind torso)
|
||||
const glm::vec3 SPHERE_TO_TORSO(-250.f, -300.f, -300.f);
|
||||
position = SPHERE_TO_TORSO + position;
|
||||
palm.setRawPosition(position);
|
||||
glm::quat rotation(data.rot_quat[3], -data.rot_quat[0], data.rot_quat[1], -data.rot_quat[2]);
|
||||
|
||||
// Rotate about controller
|
||||
rotation = glm::angleAxis(180.0f, 0.f, 1.f, 0.f) * rotation;
|
||||
const glm::vec3 PALM_VECTOR(0.0f, -1.0f, 0.0f);
|
||||
palm.setRawNormal(rotation * PALM_VECTOR);
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ AvatarData::AvatarData(Node* owningNode) :
|
|||
_leaderUUID(),
|
||||
_handState(0),
|
||||
_keyState(NO_KEY_DOWN),
|
||||
_isChatCirclingEnabled(false),
|
||||
_headData(NULL),
|
||||
_handData(NULL)
|
||||
{
|
||||
|
@ -120,6 +121,9 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
setSemiNibbleAt(bitItems,HAND_STATE_START_BIT,_handState);
|
||||
// faceshift state
|
||||
if (_headData->_isFaceshiftConnected) { setAtBit(bitItems, IS_FACESHIFT_CONNECTED); }
|
||||
if (_isChatCirclingEnabled) {
|
||||
setAtBit(bitItems, IS_CHAT_CIRCLING_ENABLED);
|
||||
}
|
||||
*destinationBuffer++ = bitItems;
|
||||
|
||||
// If it is connected, pack up the data
|
||||
|
@ -248,6 +252,8 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
|
||||
_headData->_isFaceshiftConnected = oneAtBit(bitItems, IS_FACESHIFT_CONNECTED);
|
||||
|
||||
_isChatCirclingEnabled = oneAtBit(bitItems, IS_CHAT_CIRCLING_ENABLED);
|
||||
|
||||
// If it is connected, pack up the data
|
||||
if (_headData->_isFaceshiftConnected) {
|
||||
memcpy(&_headData->_leftEyeBlink, sourceBuffer, sizeof(float));
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
const int KEY_STATE_START_BIT = 0; // 1st and 2nd bits
|
||||
const int HAND_STATE_START_BIT = 2; // 3rd and 4th bits
|
||||
const int IS_FACESHIFT_CONNECTED = 4; // 5th bit
|
||||
const int IS_CHAT_CIRCLING_ENABLED = 5;
|
||||
|
||||
const float MAX_AUDIO_LOUDNESS = 1000.0; // close enough for mouth animation
|
||||
|
||||
|
@ -93,6 +94,8 @@ public:
|
|||
const std::string& setChatMessage() const { return _chatMessage; }
|
||||
QString getQStringChatMessage() { return QString(_chatMessage.data()); }
|
||||
|
||||
bool isChatCirclingEnabled() const { return _isChatCirclingEnabled; }
|
||||
|
||||
const QUuid& getLeaderUUID() const { return _leaderUUID; }
|
||||
|
||||
void setHeadData(HeadData* headData) { _headData = headData; }
|
||||
|
@ -124,6 +127,8 @@ protected:
|
|||
// chat message
|
||||
std::string _chatMessage;
|
||||
|
||||
bool _isChatCirclingEnabled;
|
||||
|
||||
std::vector<JointData> _joints;
|
||||
|
||||
HeadData* _headData;
|
||||
|
|
|
@ -113,20 +113,20 @@ PerformanceWarning::~PerformanceWarning() {
|
|||
if ((_alwaysDisplay || _renderWarningsOn) && elapsedmsec > 1) {
|
||||
if (elapsedmsec > 1000) {
|
||||
double elapsedsec = (end - _start) / 1000000.0;
|
||||
qDebug("%s took %lf seconds %s\n", _message, elapsedsec, (_alwaysDisplay ? "" : "WARNING!") );
|
||||
qDebug("%s took %.2lf seconds %s\n", _message, elapsedsec, (_alwaysDisplay ? "" : "WARNING!") );
|
||||
} else {
|
||||
if (_suppressShortTimings) {
|
||||
if (elapsedmsec > 10) {
|
||||
qDebug("%s took %lf milliseconds %s\n", _message, elapsedmsec,
|
||||
qDebug("%s took %.1lf milliseconds %s\n", _message, elapsedmsec,
|
||||
(_alwaysDisplay || (elapsedmsec < 10) ? "" : "WARNING!"));
|
||||
}
|
||||
} else {
|
||||
qDebug("%s took %lf milliseconds %s\n", _message, elapsedmsec,
|
||||
qDebug("%s took %.2lf milliseconds %s\n", _message, elapsedmsec,
|
||||
(_alwaysDisplay || (elapsedmsec < 10) ? "" : "WARNING!"));
|
||||
}
|
||||
}
|
||||
} else if (_alwaysDisplay) {
|
||||
qDebug("%s took %lf milliseconds\n", _message, elapsedmsec);
|
||||
qDebug("%s took %.2lf milliseconds\n", _message, elapsedmsec);
|
||||
}
|
||||
// if the caller gave us a pointer to store the running total, track it now.
|
||||
if (_runningTotal) {
|
||||
|
|
Loading…
Reference in a new issue