mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 14:24:22 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into bugfixes
This commit is contained in:
commit
51f97f65fd
3 changed files with 119 additions and 43 deletions
|
@ -371,12 +371,12 @@ void Application::paintGL() {
|
|||
_myCamera.setUpShift (0.0f);
|
||||
_myCamera.setDistance (0.0f);
|
||||
_myCamera.setTightness (0.0f); // Camera is directly connected to head without smoothing
|
||||
_myCamera.setTargetPosition(_myAvatar.getHeadJointPosition());
|
||||
_myCamera.setTargetPosition(_myAvatar.getHead().calculateAverageEyePosition());
|
||||
_myCamera.setTargetRotation(_myAvatar.getHead().getOrientation());
|
||||
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
|
||||
_myCamera.setTightness(0.0f); // In first person, camera follows head exactly without delay
|
||||
_myCamera.setTargetPosition(_myAvatar.getEyeLevelPosition());
|
||||
_myCamera.setTargetPosition(_myAvatar.getHead().calculateAverageEyePosition());
|
||||
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation());
|
||||
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||
|
@ -386,15 +386,7 @@ void Application::paintGL() {
|
|||
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||
_myCamera.setTightness(0.0f);
|
||||
_myCamera.setDistance(0.3f);
|
||||
glm::vec3 targetPosition = _myAvatar.getUprightHeadPosition();
|
||||
if (_myAvatar.getHead().getFaceModel().isActive()) {
|
||||
// make sure we're aligned to the blend face eyes
|
||||
glm::vec3 leftEyePosition, rightEyePosition;
|
||||
if (_myAvatar.getHead().getFaceModel().getEyePositions(leftEyePosition, rightEyePosition)) {
|
||||
targetPosition = (leftEyePosition + rightEyePosition) * 0.5f;
|
||||
}
|
||||
}
|
||||
_myCamera.setTargetPosition(targetPosition);
|
||||
_myCamera.setTargetPosition(_myAvatar.getHead().calculateAverageEyePosition());
|
||||
_myCamera.setTargetRotation(_myAvatar.getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PIf, 0.0f)));
|
||||
}
|
||||
|
||||
|
@ -1765,7 +1757,7 @@ Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, con
|
|||
float distance;
|
||||
if (rayIntersectsSphere(mouseRayOrigin, mouseRayDirection, headPosition,
|
||||
HEAD_SPHERE_RADIUS * avatar->getHead().getScale(), distance)) {
|
||||
eyePosition = avatar->getHead().getEyePosition();
|
||||
eyePosition = avatar->getHead().calculateAverageEyePosition();
|
||||
_lookatIndicatorScale = avatar->getHead().getScale();
|
||||
_lookatOtherPosition = headPosition;
|
||||
nodeUUID = avatar->getOwningNode()->getUUID();
|
||||
|
@ -1932,10 +1924,15 @@ void Application::update(float deltaTime) {
|
|||
if (_lookatTargetAvatar && !_faceshift.isActive()) {
|
||||
// If the mouse is over another avatar's head...
|
||||
_myAvatar.getHead().setLookAtPosition(lookAtSpot);
|
||||
|
||||
} else if (_isHoverVoxel && !_faceshift.isActive()) {
|
||||
// Look at the hovered voxel
|
||||
lookAtSpot = getMouseVoxelWorldCoordinates(_hoverVoxel);
|
||||
_myAvatar.getHead().setLookAtPosition(lookAtSpot);
|
||||
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR && !_faceshift.isActive()) {
|
||||
_myAvatar.getHead().setLookAtPosition(_myCamera.getPosition());
|
||||
|
||||
} else {
|
||||
// Just look in direction of the mouse ray
|
||||
const float FAR_AWAY_STARE = TREE_SCALE;
|
||||
|
@ -2338,8 +2335,13 @@ void Application::updateAvatar(float deltaTime) {
|
|||
}
|
||||
|
||||
void Application::queryVoxels() {
|
||||
// Need to update this to support multiple different servers...
|
||||
|
||||
// if voxels are disabled, then don't send this at all...
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// These will be the same for all servers, so we can set them up once and then reuse for each server we send to.
|
||||
_voxelQuery.setCameraPosition(_viewFrustum.getPosition());
|
||||
_voxelQuery.setCameraOrientation(_viewFrustum.getOrientation());
|
||||
_voxelQuery.setCameraFov(_viewFrustum.getFieldOfView());
|
||||
|
@ -2348,24 +2350,90 @@ void Application::queryVoxels() {
|
|||
_voxelQuery.setCameraFarClip(_viewFrustum.getFarClip());
|
||||
_voxelQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition());
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
// send head/hand data to the avatar mixer and voxel server
|
||||
unsigned char voxelQueryPacket[MAX_PACKET_SIZE];
|
||||
unsigned char* endOfVoxelQueryPacket = voxelQueryPacket;
|
||||
|
||||
endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, PACKET_TYPE_VOXEL_QUERY);
|
||||
|
||||
QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122();
|
||||
memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size());
|
||||
endOfVoxelQueryPacket += ownerUUID.size();
|
||||
|
||||
endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket);
|
||||
|
||||
const char nodeTypesOfInterest[] = { NODE_TYPE_VOXEL_SERVER };
|
||||
controlledBroadcastToNodes(voxelQueryPacket, endOfVoxelQueryPacket - voxelQueryPacket,
|
||||
nodeTypesOfInterest, sizeof(nodeTypesOfInterest));
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
// Iterate all of the nodes, and get a count of how many voxel servers we have...
|
||||
int voxelServerCount = 0;
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
// only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER
|
||||
if (node->getActiveSocket() != NULL && node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
|
||||
// get the server bounds for this server
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
const JurisdictionMap& map = (_voxelServerJurisdictions)[nodeUUID];
|
||||
|
||||
unsigned char* rootCode = map.getRootOctalCode();
|
||||
|
||||
if (rootCode) {
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverBounds.scale(TREE_SCALE);
|
||||
|
||||
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
|
||||
|
||||
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
||||
voxelServerCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure there's at least one voxel server
|
||||
if (voxelServerCount < 1) {
|
||||
return; // no voxel servers to talk to, we can bail.
|
||||
}
|
||||
|
||||
// set our preferred PPS to be exactly evenly divided among all of the voxel servers...
|
||||
int perServerPPS = DEFAULT_MAX_VOXEL_PPS/voxelServerCount;
|
||||
|
||||
_voxelQuery.setMaxVoxelPacketsPerSecond(perServerPPS);
|
||||
|
||||
UDPSocket* nodeSocket = NodeList::getInstance()->getNodeSocket();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
// only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER
|
||||
if (node->getActiveSocket() != NULL && node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
|
||||
|
||||
// get the server bounds for this server
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
const JurisdictionMap& map = (_voxelServerJurisdictions)[nodeUUID];
|
||||
|
||||
unsigned char* rootCode = map.getRootOctalCode();
|
||||
|
||||
if (rootCode) {
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverBounds.scale(TREE_SCALE);
|
||||
|
||||
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
|
||||
|
||||
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
||||
// set up the packet for sending...
|
||||
unsigned char* endOfVoxelQueryPacket = voxelQueryPacket;
|
||||
|
||||
// insert packet type/version and node UUID
|
||||
endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, PACKET_TYPE_VOXEL_QUERY);
|
||||
QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122();
|
||||
memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size());
|
||||
endOfVoxelQueryPacket += ownerUUID.size();
|
||||
|
||||
// encode the query data...
|
||||
endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket);
|
||||
|
||||
int packetLength = endOfVoxelQueryPacket - voxelQueryPacket;
|
||||
|
||||
nodeSocket->send(node->getActiveSocket(), voxelQueryPacket, packetLength);
|
||||
|
||||
// Feed number of bytes to corresponding channel of the bandwidth meter
|
||||
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2792,9 +2860,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
}
|
||||
|
||||
// Render my own Avatar
|
||||
if (whichCamera.getMode() == CAMERA_MODE_MIRROR && !_faceshift.isActive()) {
|
||||
_myAvatar.getHead().setLookAtPosition(whichCamera.getPosition());
|
||||
}
|
||||
_myAvatar.render(whichCamera.getMode() == CAMERA_MODE_MIRROR,
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls));
|
||||
_myAvatar.setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors));
|
||||
|
|
|
@ -238,6 +238,11 @@ void Head::simulate(float deltaTime, bool isMine) {
|
|||
}
|
||||
|
||||
_faceModel.simulate(deltaTime);
|
||||
|
||||
calculateGeometry();
|
||||
|
||||
// the blend face may have custom eye meshes
|
||||
_faceModel.getEyePositions(_leftEyePosition, _rightEyePosition);
|
||||
}
|
||||
|
||||
void Head::calculateGeometry() {
|
||||
|
@ -286,8 +291,6 @@ void Head::render(float alpha, bool isMine) {
|
|||
_renderAlpha = alpha;
|
||||
|
||||
if (!(_videoFace.render(alpha) || _faceModel.render(alpha))) {
|
||||
calculateGeometry();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_RESCALE_NORMAL);
|
||||
|
||||
|
@ -299,11 +302,6 @@ void Head::render(float alpha, bool isMine) {
|
|||
renderNose();
|
||||
renderEyeBrows();
|
||||
}
|
||||
|
||||
if (_faceModel.isActive()) {
|
||||
// the blend face may have custom eye meshes
|
||||
_faceModel.getEyePositions(_leftEyePosition, _rightEyePosition);
|
||||
}
|
||||
|
||||
if (_renderLookatVectors) {
|
||||
renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "Faceshift.h"
|
||||
#include "Menu.h"
|
||||
#include "Util.h"
|
||||
|
||||
using namespace fs;
|
||||
using namespace std;
|
||||
|
@ -63,11 +64,23 @@ void Faceshift::update() {
|
|||
}
|
||||
float averageEyePitch = (_eyeGazeLeftPitch + _eyeGazeRightPitch) / 2.0f;
|
||||
float averageEyeYaw = (_eyeGazeLeftYaw + _eyeGazeRightYaw) / 2.0f;
|
||||
|
||||
// get the gaze relative to the window
|
||||
glm::vec3 eyeEulers = safeEulerAngles(_headRotation * glm::quat(glm::radians(glm::vec3(
|
||||
averageEyePitch, averageEyeYaw, 0.0f))));
|
||||
|
||||
// smooth relative to the window
|
||||
const float LONG_TERM_AVERAGE_SMOOTHING = 0.999f;
|
||||
_longTermAverageEyePitch = glm::mix(averageEyePitch, _longTermAverageEyePitch, LONG_TERM_AVERAGE_SMOOTHING);
|
||||
_longTermAverageEyeYaw = glm::mix(averageEyeYaw, _longTermAverageEyeYaw, LONG_TERM_AVERAGE_SMOOTHING);
|
||||
_estimatedEyePitch = averageEyePitch - _longTermAverageEyePitch;
|
||||
_estimatedEyeYaw = averageEyeYaw - _longTermAverageEyeYaw;
|
||||
_longTermAverageEyePitch = glm::mix(eyeEulers.x, _longTermAverageEyePitch, LONG_TERM_AVERAGE_SMOOTHING);
|
||||
_longTermAverageEyeYaw = glm::mix(eyeEulers.y, _longTermAverageEyeYaw, LONG_TERM_AVERAGE_SMOOTHING);
|
||||
|
||||
// back to head-relative
|
||||
float windowEyePitch = eyeEulers.x - _longTermAverageEyePitch;
|
||||
float windowEyeYaw = eyeEulers.y - _longTermAverageEyeYaw;
|
||||
glm::vec3 relativeEyeEulers = safeEulerAngles(glm::inverse(_headRotation) * glm::quat(glm::radians(glm::vec3(
|
||||
windowEyePitch, windowEyeYaw, 0.0f))));
|
||||
_estimatedEyePitch = relativeEyeEulers.x;
|
||||
_estimatedEyeYaw = relativeEyeEulers.y;
|
||||
}
|
||||
|
||||
void Faceshift::reset() {
|
||||
|
|
Loading…
Reference in a new issue