mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 22:30:43 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into compressed_packets
This commit is contained in:
commit
70213630e1
27 changed files with 399 additions and 114 deletions
|
@ -146,6 +146,7 @@ void AvatarMixer::run() {
|
|||
case PACKET_TYPE_INJECT_AUDIO:
|
||||
broadcastAvatarData(nodeList, nodeUUID, &nodeAddress);
|
||||
break;
|
||||
case PACKET_TYPE_KILL_NODE:
|
||||
case PACKET_TYPE_AVATAR_URLS:
|
||||
case PACKET_TYPE_AVATAR_FACE_VIDEO:
|
||||
nodeUUID = QUuid::fromRfc4122(QByteArray((char*) packetData + numBytesForPacketHeader(packetData),
|
||||
|
@ -156,7 +157,8 @@ void AvatarMixer::run() {
|
|||
nodeList->getNodeSocket()->send(node->getActiveSocket(), packetData, receivedBytes);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// let node kills fall through to default behavior
|
||||
|
||||
default:
|
||||
// hand this off to the NodeList
|
||||
nodeList->processNodeData(&nodeAddress, packetData, receivedBytes);
|
||||
|
|
16
interface/resources/shaders/shadow_map.frag
Normal file
16
interface/resources/shaders/shadow_map.frag
Normal file
|
@ -0,0 +1,16 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// shadow_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 11/21/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = gl_Color * mix(vec4(0.8, 0.8, 0.8, 1.0), vec4(1.0, 1.0, 1.0, 1.0),
|
||||
shadow2D(shadowMap, gl_TexCoord[0].stp));
|
||||
}
|
|
@ -424,12 +424,15 @@ void Application::paintGL() {
|
|||
whichCamera = _viewFrustumOffsetCamera;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Shadows)) {
|
||||
updateShadowMap();
|
||||
}
|
||||
|
||||
if (OculusManager::isConnected()) {
|
||||
displayOculus(whichCamera);
|
||||
|
||||
} else {
|
||||
_glowEffect.prepare();
|
||||
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
@ -1391,6 +1394,9 @@ void Application::terminate() {
|
|||
_rearMirrorTools->saveSettings(_settings);
|
||||
_settings->sync();
|
||||
|
||||
// let the avatar mixer know we're out
|
||||
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
|
||||
|
||||
if (_enableNetworkThread) {
|
||||
_stopNetworkReceiveThread = true;
|
||||
pthread_join(_networkReceiveThread, NULL);
|
||||
|
@ -1873,7 +1879,7 @@ bool Application::isLookingAtMyAvatar(Avatar* avatar) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void Application::renderLookatIndicator(glm::vec3 pointOfInterest, Camera& whichCamera) {
|
||||
void Application::renderLookatIndicator(glm::vec3 pointOfInterest) {
|
||||
|
||||
const float DISTANCE_FROM_HEAD_SPHERE = 0.1f * _lookatIndicatorScale;
|
||||
const float INDICATOR_RADIUS = 0.1f * _lookatIndicatorScale;
|
||||
|
@ -1966,6 +1972,21 @@ void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::
|
|||
}
|
||||
node->unlock();
|
||||
}
|
||||
|
||||
// simulate avatar fades
|
||||
for (vector<Avatar*>::iterator fade = _avatarFades.begin(); fade != _avatarFades.end(); fade++) {
|
||||
Avatar* avatar = *fade;
|
||||
const float SHRINK_RATE = 0.9f;
|
||||
avatar->setNewScale(avatar->getNewScale() * SHRINK_RATE);
|
||||
const float MINIMUM_SCALE = 0.001f;
|
||||
if (avatar->getNewScale() < MINIMUM_SCALE) {
|
||||
delete avatar;
|
||||
_avatarFades.erase(fade--);
|
||||
|
||||
} else {
|
||||
avatar->simulate(deltaTime, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::updateMouseRay(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection) {
|
||||
|
@ -2189,10 +2210,8 @@ void Application::updateHandAndTouch(float deltaTime) {
|
|||
float TOUCH_YAW_SCALE = -0.25f;
|
||||
float TOUCH_PITCH_SCALE = -12.5f;
|
||||
float FIXED_TOUCH_TIMESTEP = 0.016f;
|
||||
const float MAX_PITCH = 90.0f;
|
||||
_yawFromTouch += ((_touchAvgX - _lastTouchAvgX) * TOUCH_YAW_SCALE * FIXED_TOUCH_TIMESTEP);
|
||||
_pitchFromTouch = glm::clamp(_pitchFromTouch + (_touchAvgY - _lastTouchAvgY) * TOUCH_PITCH_SCALE *
|
||||
FIXED_TOUCH_TIMESTEP, -MAX_PITCH, MAX_PITCH);
|
||||
_pitchFromTouch += ((_touchAvgY - _lastTouchAvgY) * TOUCH_PITCH_SCALE * FIXED_TOUCH_TIMESTEP);
|
||||
_lastTouchAvgX = _touchAvgX;
|
||||
_lastTouchAvgY = _touchAvgY;
|
||||
}
|
||||
|
@ -2444,8 +2463,12 @@ void Application::updateAvatar(float deltaTime) {
|
|||
* glm::quat(glm::vec3(0, _yawFromTouch, 0)));
|
||||
_yawFromTouch = 0.f;
|
||||
|
||||
// apply pitch from touch
|
||||
_myAvatar.getHead().setMousePitch(_myAvatar.getHead().getMousePitch() + _pitchFromTouch);
|
||||
_pitchFromTouch = 0.0f;
|
||||
|
||||
// Update my avatar's state from gyros and/or webcam
|
||||
_myAvatar.updateFromGyrosAndOrWebcam(_pitchFromTouch, Menu::getInstance()->isOptionChecked(MenuOption::TurnWithHead));
|
||||
_myAvatar.updateFromGyrosAndOrWebcam(Menu::getInstance()->isOptionChecked(MenuOption::TurnWithHead));
|
||||
|
||||
// Update head mouse from faceshift if active
|
||||
if (_faceshift.isActive()) {
|
||||
|
@ -2501,8 +2524,8 @@ void Application::updateAvatar(float deltaTime) {
|
|||
float yaw, pitch, roll;
|
||||
OculusManager::getEulerAngles(yaw, pitch, roll);
|
||||
|
||||
_myAvatar.getHead().setYaw(yaw + _yawFromTouch);
|
||||
_myAvatar.getHead().setPitch(pitch + _pitchFromTouch);
|
||||
_myAvatar.getHead().setYaw(yaw);
|
||||
_myAvatar.getHead().setPitch(pitch);
|
||||
_myAvatar.getHead().setRoll(roll);
|
||||
}
|
||||
|
||||
|
@ -2764,6 +2787,80 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
|||
viewFrustum.calculate();
|
||||
}
|
||||
|
||||
glm::vec3 Application::getSunDirection() {
|
||||
return glm::normalize(_environment.getClosestData(_myCamera.getPosition()).getSunLocation() - _myCamera.getPosition());
|
||||
}
|
||||
|
||||
void Application::updateShadowMap() {
|
||||
QOpenGLFramebufferObject* fbo = _textureCache.getShadowFramebufferObject();
|
||||
fbo->bind();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glViewport(0, 0, fbo->width(), fbo->height());
|
||||
|
||||
glm::vec3 lightDirection = -getSunDirection();
|
||||
glm::quat rotation = glm::inverse(rotationBetween(IDENTITY_FRONT, lightDirection));
|
||||
glm::vec3 translation = glm::vec3();
|
||||
float nearScale = 0.0f;
|
||||
const float MAX_SHADOW_DISTANCE = 2.0f;
|
||||
float farScale = (MAX_SHADOW_DISTANCE - _viewFrustum.getNearClip()) / (_viewFrustum.getFarClip() - _viewFrustum.getNearClip());
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
glm::vec3 points[] = {
|
||||
rotation * (glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), nearScale) + translation),
|
||||
rotation * (glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), nearScale) + translation),
|
||||
rotation * (glm::mix(_viewFrustum.getNearBottomLeft(), _viewFrustum.getFarBottomLeft(), nearScale) + translation),
|
||||
rotation * (glm::mix(_viewFrustum.getNearBottomRight(), _viewFrustum.getFarBottomRight(), nearScale) + translation),
|
||||
rotation * (glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), farScale) + translation),
|
||||
rotation * (glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), farScale) + translation),
|
||||
rotation * (glm::mix(_viewFrustum.getNearBottomLeft(), _viewFrustum.getFarBottomLeft(), farScale) + translation),
|
||||
rotation * (glm::mix(_viewFrustum.getNearBottomRight(), _viewFrustum.getFarBottomRight(), farScale) + translation) };
|
||||
glm::vec3 minima(FLT_MAX, FLT_MAX, FLT_MAX), maxima(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
for (int i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
|
||||
minima = glm::min(minima, points[i]);
|
||||
maxima = glm::max(maxima, points[i]);
|
||||
}
|
||||
|
||||
// stretch out our extents in z so that we get all of the avatars
|
||||
minima.z -= _viewFrustum.getFarClip() * 0.5f;
|
||||
maxima.z += _viewFrustum.getFarClip() * 0.5f;
|
||||
|
||||
// save the combined matrix for rendering
|
||||
_shadowMatrix = glm::transpose(glm::translate(0.5f, 0.5f, 0.5f) * glm::scale(0.5f, 0.5f, 0.5f) *
|
||||
glm::ortho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z) *
|
||||
glm::mat4_cast(rotation) * glm::translate(translation));
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
|
||||
|
||||
// store view matrix without translation, which we'll use for precision-sensitive objects
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix);
|
||||
_viewMatrixTranslation = translation;
|
||||
|
||||
glTranslatef(translation.x, translation.y, translation.z);
|
||||
|
||||
renderAvatars(true);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
fbo->release();
|
||||
|
||||
glViewport(0, 0, _glWidget->width(), _glWidget->height());
|
||||
}
|
||||
|
||||
// this shader is an adaptation (HLSL -> GLSL, removed conditional) of the one in the Oculus sample
|
||||
// code (Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.cpp), which is under the Apache license
|
||||
// (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
@ -2906,15 +3003,14 @@ void Application::displayOculus(Camera& whichCamera) {
|
|||
const GLfloat WHITE_SPECULAR_COLOR[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
const GLfloat NO_SPECULAR_COLOR[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
|
||||
void Application::setupWorldLight(Camera& whichCamera) {
|
||||
void Application::setupWorldLight() {
|
||||
|
||||
// Setup 3D lights (after the camera transform, so that they are positioned in world space)
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||
|
||||
glm::vec3 relativeSunLoc = glm::normalize(_environment.getClosestData(whichCamera.getPosition()).getSunLocation() -
|
||||
whichCamera.getPosition());
|
||||
GLfloat light_position0[] = { relativeSunLoc.x, relativeSunLoc.y, relativeSunLoc.z, 0.0 };
|
||||
glm::vec3 sunDirection = getSunDirection();
|
||||
GLfloat light_position0[] = { sunDirection.x, sunDirection.y, sunDirection.z, 0.0 };
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
|
||||
GLfloat ambient_color[] = { 0.7, 0.7, 0.8 };
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color);
|
||||
|
@ -2972,7 +3068,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
glTranslatef(_viewMatrixTranslation.x, _viewMatrixTranslation.y, _viewMatrixTranslation.z);
|
||||
|
||||
// Setup 3D lights (after the camera transform, so that they are positioned in world space)
|
||||
setupWorldLight(whichCamera);
|
||||
setupWorldLight();
|
||||
|
||||
if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Stars)) {
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
|
@ -3109,44 +3205,11 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
}
|
||||
}
|
||||
|
||||
_myAvatar.renderScreenTint(SCREEN_TINT_BEFORE_AVATARS, whichCamera);
|
||||
_myAvatar.renderScreenTint(SCREEN_TINT_BEFORE_AVATARS);
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... Avatars...");
|
||||
renderAvatars(whichCamera.getMode() == CAMERA_MODE_MIRROR, selfAvatarOnly);
|
||||
|
||||
|
||||
if (!selfAvatarOnly) {
|
||||
// Render avatars of other nodes
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
node->lock();
|
||||
|
||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||
Avatar *avatar = (Avatar *)node->getLinkedData();
|
||||
if (!avatar->isInitialized()) {
|
||||
avatar->init();
|
||||
}
|
||||
avatar->render(false, Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls));
|
||||
avatar->setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors));
|
||||
}
|
||||
|
||||
node->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Render my own Avatar
|
||||
_myAvatar.render(whichCamera.getMode() == CAMERA_MODE_MIRROR,
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls));
|
||||
_myAvatar.setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors));
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::LookAtIndicator) && _lookatTargetAvatar) {
|
||||
renderLookatIndicator(_lookatOtherPosition, whichCamera);
|
||||
}
|
||||
}
|
||||
|
||||
_myAvatar.renderScreenTint(SCREEN_TINT_AFTER_AVATARS, whichCamera);
|
||||
_myAvatar.renderScreenTint(SCREEN_TINT_AFTER_AVATARS);
|
||||
|
||||
if (!selfAvatarOnly) {
|
||||
// Render the world box
|
||||
|
@ -3768,7 +3831,47 @@ void Application::renderCoverageMapsRecursively(CoverageMap* map) {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
return;
|
||||
}
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... Avatars...");
|
||||
|
||||
if (!selfAvatarOnly) {
|
||||
// Render avatars of other nodes
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
node->lock();
|
||||
|
||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||
Avatar *avatar = (Avatar *)node->getLinkedData();
|
||||
if (!avatar->isInitialized()) {
|
||||
avatar->init();
|
||||
}
|
||||
avatar->render(false, Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls));
|
||||
avatar->setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors));
|
||||
}
|
||||
|
||||
node->unlock();
|
||||
}
|
||||
|
||||
// render avatar fades
|
||||
Glower glower;
|
||||
for (vector<Avatar*>::iterator fade = _avatarFades.begin(); fade != _avatarFades.end(); fade++) {
|
||||
(*fade)->render(false, Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls));
|
||||
}
|
||||
}
|
||||
|
||||
// Render my own Avatar
|
||||
_myAvatar.render(forceRenderHead, Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls));
|
||||
_myAvatar.setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors));
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::LookAtIndicator) && _lookatTargetAvatar) {
|
||||
renderLookatIndicator(_lookatOtherPosition);
|
||||
}
|
||||
}
|
||||
|
||||
// renderViewFrustum()
|
||||
//
|
||||
|
@ -4204,8 +4307,17 @@ void Application::nodeKilled(Node* node) {
|
|||
_voxelServerSceneStats.erase(nodeUUID);
|
||||
}
|
||||
_voxelSceneStatsLock.unlock();
|
||||
} else if (node->getLinkedData() == _lookatTargetAvatar) {
|
||||
_lookatTargetAvatar = NULL;
|
||||
|
||||
} else if (node->getType() == NODE_TYPE_AGENT) {
|
||||
Avatar* avatar = static_cast<Avatar*>(node->getLinkedData());
|
||||
if (avatar == _lookatTargetAvatar) {
|
||||
_lookatTargetAvatar = NULL;
|
||||
}
|
||||
|
||||
// take over the avatar in order to fade it out
|
||||
node->setLinkedData(NULL);
|
||||
|
||||
_avatarFades.push_back(avatar);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -153,12 +153,14 @@ public:
|
|||
static void controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes,
|
||||
const char* nodeTypes, int numNodeTypes);
|
||||
|
||||
void setupWorldLight(Camera& whichCamera);
|
||||
void setupWorldLight();
|
||||
|
||||
/// Loads a view matrix that incorporates the specified model translation without the precision issues that can
|
||||
/// result from matrix multiplication at high translation magnitudes.
|
||||
void loadTranslatedViewMatrix(const glm::vec3& translation);
|
||||
|
||||
const glm::mat4& getShadowMatrix() const { return _shadowMatrix; }
|
||||
|
||||
/// Computes the off-axis frustum parameters for the view frustum, taking mirroring into account.
|
||||
void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& near,
|
||||
float& far, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const;
|
||||
|
@ -260,17 +262,21 @@ private:
|
|||
glm::vec3& eyePosition, QUuid &nodeUUID);
|
||||
bool isLookingAtMyAvatar(Avatar* avatar);
|
||||
|
||||
void renderLookatIndicator(glm::vec3 pointOfInterest, Camera& whichCamera);
|
||||
void renderLookatIndicator(glm::vec3 pointOfInterest);
|
||||
void renderFollowIndicator();
|
||||
void updateAvatar(float deltaTime);
|
||||
void updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection);
|
||||
void queryVoxels();
|
||||
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
|
||||
|
||||
glm::vec3 getSunDirection();
|
||||
|
||||
void updateShadowMap();
|
||||
void displayOculus(Camera& whichCamera);
|
||||
void displaySide(Camera& whichCamera, bool selfAvatarOnly = false);
|
||||
void displayOverlay();
|
||||
void displayStats();
|
||||
void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false);
|
||||
void renderViewFrustum(ViewFrustum& viewFrustum);
|
||||
|
||||
void checkBandwidthMeterClick();
|
||||
|
@ -352,6 +358,8 @@ private:
|
|||
glm::mat4 _untranslatedViewMatrix;
|
||||
glm::vec3 _viewMatrixTranslation;
|
||||
|
||||
glm::mat4 _shadowMatrix;
|
||||
|
||||
Environment _environment;
|
||||
|
||||
int _headMouseX, _headMouseY;
|
||||
|
@ -463,6 +471,7 @@ private:
|
|||
QReadWriteLock _voxelSceneStatsLock;
|
||||
|
||||
std::vector<VoxelFade> _voxelFades;
|
||||
std::vector<Avatar*> _avatarFades;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__Application__) */
|
||||
|
|
|
@ -173,6 +173,9 @@ void DataServerClient::processSendFromDataServer(unsigned char* packetData, int
|
|||
|
||||
if (coordinateItems.size() == 3) {
|
||||
|
||||
// send a node kill request, indicating to other clients that they should play the "disappeared" effect
|
||||
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
|
||||
|
||||
qDebug() << "Changing domain to" << valueList[i].toLocal8Bit().constData() <<
|
||||
"and position to" << valueList[i + 1].toLocal8Bit().constData() <<
|
||||
"to go to" << userString << "\n";
|
||||
|
|
|
@ -272,6 +272,7 @@ Menu::Menu() :
|
|||
SLOT(cycleRenderMode()));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ParticleCloud, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Shadows, 0, false);
|
||||
|
||||
|
||||
QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options");
|
||||
|
@ -913,6 +914,9 @@ void Menu::goToDomain() {
|
|||
newHostname = domainDialog.textValue();
|
||||
}
|
||||
|
||||
// send a node kill request, indicating to other clients that they should play the "disappeared" effect
|
||||
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
|
||||
|
||||
// give our nodeList the new domain-server hostname
|
||||
NodeList::getInstance()->setDomainHostname(domainDialog.textValue());
|
||||
}
|
||||
|
@ -952,8 +956,11 @@ void Menu::goToLocation() {
|
|||
glm::vec3 newAvatarPos(x, y, z);
|
||||
|
||||
if (newAvatarPos != avatarPos) {
|
||||
// send a node kill request, indicating to other clients that they should play the "disappeared" effect
|
||||
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
|
||||
|
||||
qDebug("Going To Location: %f, %f, %f...\n", x, y, z);
|
||||
myAvatar->setPosition(newAvatarPos);
|
||||
myAvatar->setPosition(newAvatarPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -229,6 +229,7 @@ namespace MenuOption {
|
|||
const QString RunTimingTests = "Run Timing Tests";
|
||||
const QString SendVoxelColors = "Colored Voxels";
|
||||
const QString SettingsImport = "Import Settings";
|
||||
const QString Shadows = "Shadows";
|
||||
const QString SettingsExport = "Export Settings";
|
||||
const QString ShowAllLocalVoxels = "Show All Local Voxels";
|
||||
const QString ShowTrueColors = "Show TRUE Colors";
|
||||
|
|
|
@ -519,6 +519,13 @@ void VoxelSystem::initVoxelMemory() {
|
|||
_perlinModulateProgram.bind();
|
||||
_perlinModulateProgram.setUniformValue("permutationNormalTexture", 0);
|
||||
_perlinModulateProgram.release();
|
||||
|
||||
_shadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/shadow_map.frag");
|
||||
_shadowMapProgram.link();
|
||||
|
||||
_shadowMapProgram.bind();
|
||||
_shadowMapProgram.setUniformValue("shadowMap", 0);
|
||||
_shadowMapProgram.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1092,6 +1099,7 @@ glm::vec3 VoxelSystem::computeVoxelVertex(const glm::vec3& startVertex, float vo
|
|||
}
|
||||
|
||||
ProgramObject VoxelSystem::_perlinModulateProgram;
|
||||
ProgramObject VoxelSystem::_shadowMapProgram;
|
||||
|
||||
void VoxelSystem::init() {
|
||||
if (_initialized) {
|
||||
|
@ -1398,20 +1406,41 @@ void VoxelSystem::render(bool texture) {
|
|||
}
|
||||
|
||||
void VoxelSystem::applyScaleAndBindProgram(bool texture) {
|
||||
glPushMatrix();
|
||||
glScalef(_treeScale, _treeScale, _treeScale);
|
||||
|
||||
if (texture) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Shadows)) {
|
||||
_shadowMapProgram.bind();
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
||||
glEnable(GL_TEXTURE_GEN_S);
|
||||
glEnable(GL_TEXTURE_GEN_T);
|
||||
glEnable(GL_TEXTURE_GEN_R);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glTexGenfv(GL_S, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[0]);
|
||||
glTexGenfv(GL_T, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[1]);
|
||||
glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[2]);
|
||||
|
||||
} else if (texture) {
|
||||
_perlinModulateProgram.bind();
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPermutationNormalTextureID());
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
glScalef(_treeScale, _treeScale, _treeScale);
|
||||
}
|
||||
|
||||
void VoxelSystem::removeScaleAndReleaseProgram(bool texture) {
|
||||
// scale back down to 1 so heads aren't massive
|
||||
glPopMatrix();
|
||||
|
||||
if (texture) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Shadows)) {
|
||||
_shadowMapProgram.release();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_GEN_S);
|
||||
glDisable(GL_TEXTURE_GEN_T);
|
||||
glDisable(GL_TEXTURE_GEN_R);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
} else if (texture) {
|
||||
_perlinModulateProgram.release();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
|
|
@ -282,6 +282,7 @@ private:
|
|||
bool _voxelsDirty;
|
||||
|
||||
static ProgramObject _perlinModulateProgram;
|
||||
static ProgramObject _shadowMapProgram;
|
||||
|
||||
int _hookID;
|
||||
std::vector<glBufferIndex> _freeIndexes;
|
||||
|
|
|
@ -439,7 +439,7 @@ static TextRenderer* textRenderer() {
|
|||
return renderer;
|
||||
}
|
||||
|
||||
void Avatar::render(bool lookingInMirror, bool renderAvatarBalls) {
|
||||
void Avatar::render(bool forceRenderHead, bool renderAvatarBalls) {
|
||||
|
||||
if (Application::getInstance()->getAvatar()->getHand().isRaveGloveActive()) {
|
||||
_hand.setRaveLights(RAVE_LIGHTS_AVATAR);
|
||||
|
@ -455,7 +455,7 @@ void Avatar::render(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
Glower glower(_moving && glm::length(toTarget) > GLOW_DISTANCE ? 1.0f : 0.0f);
|
||||
|
||||
// render body
|
||||
renderBody(lookingInMirror, renderAvatarBalls);
|
||||
renderBody(forceRenderHead, renderAvatarBalls);
|
||||
|
||||
// render sphere when far away
|
||||
const float MAX_ANGLE = 10.f;
|
||||
|
@ -709,15 +709,15 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {
|
|||
return glm::angleAxis(angle * proportion, axis);
|
||||
}
|
||||
|
||||
float Avatar::getBallRenderAlpha(int ball, bool lookingInMirror) const {
|
||||
float Avatar::getBallRenderAlpha(int ball, bool forceRenderHead) const {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
||||
void Avatar::renderBody(bool forceRenderHead, bool renderAvatarBalls) {
|
||||
|
||||
if (_head.getVideoFace().isFullFrame()) {
|
||||
// Render the full-frame video
|
||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
|
||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, forceRenderHead);
|
||||
if (alpha > 0.0f) {
|
||||
_head.getVideoFace().render(1.0f);
|
||||
}
|
||||
|
@ -726,7 +726,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
glm::vec3 skinColor, darkSkinColor;
|
||||
getSkinColors(skinColor, darkSkinColor);
|
||||
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||
float alpha = getBallRenderAlpha(b, lookingInMirror);
|
||||
float alpha = getBallRenderAlpha(b, forceRenderHead);
|
||||
|
||||
// When we have leap hands, hide part of the arms.
|
||||
if (_hand.getNumPalms() > 0) {
|
||||
|
@ -779,7 +779,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
}
|
||||
} else {
|
||||
// Render the body's voxels and head
|
||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
|
||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, forceRenderHead);
|
||||
if (alpha > 0.0f) {
|
||||
if (!_skeletonModel.render(alpha)) {
|
||||
_voxels.render(false);
|
||||
|
@ -787,7 +787,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
_head.render(alpha, false);
|
||||
}
|
||||
}
|
||||
_hand.render(lookingInMirror);
|
||||
_hand.render();
|
||||
}
|
||||
|
||||
void Avatar::getSkinColors(glm::vec3& lighter, glm::vec3& darker) {
|
||||
|
|
|
@ -141,7 +141,7 @@ public:
|
|||
void init();
|
||||
void simulate(float deltaTime, Transmitter* transmitter);
|
||||
void follow(Avatar* leadingAvatar);
|
||||
void render(bool lookingInMirror, bool renderAvatarBalls);
|
||||
void render(bool forceRenderHead, bool renderAvatarBalls);
|
||||
|
||||
//setters
|
||||
void setDisplayingLookatVectors(bool displayingLookatVectors) { _head.setRenderLookatVectors(displayingLookatVectors); }
|
||||
|
@ -255,8 +255,8 @@ private:
|
|||
|
||||
// private methods...
|
||||
glm::vec3 calculateAverageEyePosition() { return _head.calculateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat)
|
||||
float getBallRenderAlpha(int ball, bool lookingInMirror) const;
|
||||
void renderBody(bool lookingInMirror, bool renderAvatarBalls);
|
||||
float getBallRenderAlpha(int ball, bool forceRenderHead) const;
|
||||
void renderBody(bool forceRenderHead, bool renderAvatarBalls);
|
||||
void initializeBodyBalls();
|
||||
void resetBodyBalls();
|
||||
void updateHandMovementAndTouching(float deltaTime, bool enableHandMovement);
|
||||
|
|
|
@ -24,7 +24,6 @@ Hand::Hand(Avatar* owningAvatar) :
|
|||
_raveGloveInitialized(false),
|
||||
_owningAvatar(owningAvatar),
|
||||
_renderAlpha(1.0),
|
||||
_lookingInMirror(false),
|
||||
_ballColor(0.0, 0.0, 0.4)
|
||||
{
|
||||
// initialize all finger particle emitters with an invalid id as default
|
||||
|
@ -133,10 +132,9 @@ void Hand::setRaveGloveEffectsMode(QKeyEvent* event) {
|
|||
};
|
||||
}
|
||||
|
||||
void Hand::render(bool lookingInMirror) {
|
||||
void Hand::render() {
|
||||
|
||||
_renderAlpha = 1.0;
|
||||
_lookingInMirror = lookingInMirror;
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayLeapHands)) {
|
||||
if (!isRaveGloveActive()) {
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
void init();
|
||||
void reset();
|
||||
void simulate(float deltaTime, bool isMine);
|
||||
void render(bool lookingInMirror);
|
||||
void render();
|
||||
void renderRaveGloveStage();
|
||||
void setRaveLights(RaveLightsSetting setting);
|
||||
|
||||
|
@ -75,7 +75,6 @@ private:
|
|||
|
||||
Avatar* _owningAvatar;
|
||||
float _renderAlpha;
|
||||
bool _lookingInMirror;
|
||||
glm::vec3 _ballColor;
|
||||
std::vector<HandBall> _leapFingerTipBalls;
|
||||
std::vector<HandBall> _leapFingerRootBalls;
|
||||
|
|
|
@ -109,6 +109,7 @@ void Head::init() {
|
|||
|
||||
void Head::reset() {
|
||||
_yaw = _pitch = _roll = 0.0f;
|
||||
_mousePitch = 0.0f;
|
||||
_leanForward = _leanSideways = 0.0f;
|
||||
|
||||
if (USING_PHYSICAL_MOHAWK) {
|
||||
|
@ -230,6 +231,13 @@ void Head::simulate(float deltaTime, bool isMine) {
|
|||
_rightEyeBlinkVelocity = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// use data to update fake Faceshift blendshape coefficients
|
||||
const float BROW_LIFT_SCALE = 500.0f;
|
||||
const float JAW_OPEN_SCALE = 0.01f;
|
||||
const float JAW_OPEN_DEAD_ZONE = 0.75f;
|
||||
faceshift->updateFakeCoefficients(_leftEyeBlink, _rightEyeBlink, min(1.0f, _browAudioLift * BROW_LIFT_SCALE),
|
||||
glm::clamp(sqrt(_averageLoudness * JAW_OPEN_SCALE) - JAW_OPEN_DEAD_ZONE, 0.0f, 1.0f), _blendshapeCoefficients);
|
||||
}
|
||||
|
||||
// based on the nature of the lookat position, determine if the eyes can look / are looking at it.
|
||||
|
@ -325,6 +333,10 @@ void Head::setScale (float scale) {
|
|||
}
|
||||
}
|
||||
|
||||
void Head::setMousePitch(float mousePitch) {
|
||||
const float MAX_PITCH = 90.0f;
|
||||
_mousePitch = glm::clamp(mousePitch, -MAX_PITCH, MAX_PITCH);
|
||||
}
|
||||
|
||||
void Head::createMohawk() {
|
||||
srand(time(NULL));
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
void setRenderLookatVectors(bool onOff) { _renderLookatVectors = onOff; }
|
||||
|
||||
float getMousePitch() const { return _mousePitch; }
|
||||
void setMousePitch(float mousePitch) { _mousePitch = mousePitch; }
|
||||
void setMousePitch(float mousePitch);
|
||||
|
||||
glm::quat getOrientation() const;
|
||||
glm::quat getCameraOrientation () const;
|
||||
|
|
|
@ -43,7 +43,6 @@ MyAvatar::MyAvatar(Node* owningNode) :
|
|||
_mousePressed(false),
|
||||
_bodyPitchDelta(0.0f),
|
||||
_bodyRollDelta(0.0f),
|
||||
_mousePitchDelta(0.0f),
|
||||
_shouldJump(false),
|
||||
_gravity(0.0f, -1.0f, 0.0f),
|
||||
_distanceToNearestAvatar(std::numeric_limits<float>::max()),
|
||||
|
@ -373,23 +372,24 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
const float MAX_PITCH = 90.0f;
|
||||
|
||||
// Update avatar head rotation with sensor data
|
||||
void MyAvatar::updateFromGyrosAndOrWebcam(float pitchFromTouch, bool turnWithHead) {
|
||||
void MyAvatar::updateFromGyrosAndOrWebcam(bool turnWithHead) {
|
||||
Faceshift* faceshift = Application::getInstance()->getFaceshift();
|
||||
SerialInterface* gyros = Application::getInstance()->getSerialHeadSensor();
|
||||
Webcam* webcam = Application::getInstance()->getWebcam();
|
||||
glm::vec3 estimatedPosition, estimatedRotation;
|
||||
|
||||
float combinedPitch = glm::clamp(pitchFromTouch + _mousePitchDelta, -MAX_PITCH, MAX_PITCH);
|
||||
if (faceshift->isActive()) {
|
||||
estimatedPosition = faceshift->getHeadTranslation();
|
||||
estimatedRotation = safeEulerAngles(faceshift->getHeadRotation());
|
||||
// Rotate the body if the head is turned quickly
|
||||
if (turnWithHead) {
|
||||
glm::vec3 headAngularVelocity = faceshift->getHeadAngularVelocity();
|
||||
const float FACESHIFT_YAW_VIEW_SENSITIVITY = 20.f;
|
||||
const float FACESHIFT_MIN_YAW_VELOCITY = 1.0f;
|
||||
if (fabs(headAngularVelocity.y) > FACESHIFT_MIN_YAW_VELOCITY) {
|
||||
_bodyYawDelta += headAngularVelocity.y * FACESHIFT_YAW_VIEW_SENSITIVITY;
|
||||
const float FACESHIFT_YAW_TURN_SENSITIVITY = 0.25f;
|
||||
const float FACESHIFT_MIN_YAW_TURN = 10.f;
|
||||
const float FACESHIFT_MAX_YAW_TURN = 30.f;
|
||||
if ( (fabs(estimatedRotation.y) > FACESHIFT_MIN_YAW_TURN) &&
|
||||
(fabs(estimatedRotation.y) < FACESHIFT_MAX_YAW_TURN) ) {
|
||||
_bodyYawDelta += estimatedRotation.y * FACESHIFT_YAW_TURN_SENSITIVITY;
|
||||
}
|
||||
}
|
||||
} else if (gyros->isActive()) {
|
||||
|
@ -400,8 +400,7 @@ void MyAvatar::updateFromGyrosAndOrWebcam(float pitchFromTouch, bool turnWithHea
|
|||
|
||||
} else {
|
||||
if (!_leadingAvatar) {
|
||||
_head.setMousePitch(combinedPitch);
|
||||
_head.setPitch(combinedPitch);
|
||||
_head.setPitch(_head.getMousePitch());
|
||||
}
|
||||
_head.getVideoFace().clearFrame();
|
||||
|
||||
|
@ -413,7 +412,6 @@ void MyAvatar::updateFromGyrosAndOrWebcam(float pitchFromTouch, bool turnWithHea
|
|||
_head.setLeanForward(glm::mix(_head.getLeanForward(), 0.0f, RESTORE_RATE));
|
||||
return;
|
||||
}
|
||||
_head.setMousePitch(combinedPitch);
|
||||
|
||||
if (webcam->isActive()) {
|
||||
estimatedPosition = webcam->getEstimatedPosition();
|
||||
|
@ -485,7 +483,7 @@ static TextRenderer* textRenderer() {
|
|||
return renderer;
|
||||
}
|
||||
|
||||
void MyAvatar::render(bool lookingInMirror, bool renderAvatarBalls) {
|
||||
void MyAvatar::render(bool forceRenderHead, bool renderAvatarBalls) {
|
||||
|
||||
if (Application::getInstance()->getAvatar()->getHand().isRaveGloveActive()) {
|
||||
_hand.setRaveLights(RAVE_LIGHTS_AVATAR);
|
||||
|
@ -495,7 +493,7 @@ void MyAvatar::render(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f), _scale * 0.1f, 0.2f);
|
||||
|
||||
// render body
|
||||
renderBody(lookingInMirror, renderAvatarBalls);
|
||||
renderBody(forceRenderHead, renderAvatarBalls);
|
||||
|
||||
// if this is my avatar, then render my interactions with the other avatar
|
||||
_avatarTouch.render(Application::getInstance()->getCamera()->getPosition());
|
||||
|
@ -550,7 +548,7 @@ void MyAvatar::render(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
}
|
||||
}
|
||||
|
||||
void MyAvatar::renderScreenTint(ScreenTintLayer layer, Camera& whichCamera) {
|
||||
void MyAvatar::renderScreenTint(ScreenTintLayer layer) {
|
||||
|
||||
if (layer == SCREEN_TINT_BEFORE_AVATARS) {
|
||||
if (_hand.isRaveGloveActive()) {
|
||||
|
@ -560,7 +558,7 @@ void MyAvatar::renderScreenTint(ScreenTintLayer layer, Camera& whichCamera) {
|
|||
else if (layer == SCREEN_TINT_BEFORE_AVATARS) {
|
||||
if (_hand.isRaveGloveActive()) {
|
||||
// Restore the world lighting
|
||||
Application::getInstance()->setupWorldLight(whichCamera);
|
||||
Application::getInstance()->setupWorldLight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -572,6 +570,8 @@ void MyAvatar::saveData(QSettings* settings) {
|
|||
settings->setValue("bodyPitch", _bodyPitch);
|
||||
settings->setValue("bodyRoll", _bodyRoll);
|
||||
|
||||
settings->setValue("mousePitch", _head.getMousePitch());
|
||||
|
||||
settings->setValue("position_x", _position.x);
|
||||
settings->setValue("position_y", _position.y);
|
||||
settings->setValue("position_z", _position.z);
|
||||
|
@ -592,6 +592,9 @@ void MyAvatar::loadData(QSettings* settings) {
|
|||
_bodyYaw = loadSetting(settings, "bodyYaw", 0.0f);
|
||||
_bodyPitch = loadSetting(settings, "bodyPitch", 0.0f);
|
||||
_bodyRoll = loadSetting(settings, "bodyRoll", 0.0f);
|
||||
|
||||
_head.setMousePitch(loadSetting(settings, "mousePitch", 0.0f));
|
||||
|
||||
_position.x = loadSetting(settings, "position_x", 0.0f);
|
||||
_position.y = loadSetting(settings, "position_y", 0.0f);
|
||||
_position.z = loadSetting(settings, "position_z", 0.0f);
|
||||
|
@ -623,19 +626,19 @@ glm::vec3 MyAvatar::getEyeLevelPosition() const {
|
|||
glm::vec3(0.0f, _pelvisToHeadLength + _scale * BODY_BALL_RADIUS_HEAD_BASE * EYE_UP_OFFSET, 0.0f);
|
||||
}
|
||||
|
||||
float MyAvatar::getBallRenderAlpha(int ball, bool lookingInMirror) const {
|
||||
float MyAvatar::getBallRenderAlpha(int ball, bool forceRenderHead) const {
|
||||
const float RENDER_OPAQUE_OUTSIDE = _scale * 0.25f; // render opaque if greater than this distance
|
||||
const float DO_NOT_RENDER_INSIDE = _scale * 0.25f; // do not render if less than this distance
|
||||
float distanceToCamera = glm::length(Application::getInstance()->getCamera()->getPosition() - _bodyBall[ball].position);
|
||||
return (lookingInMirror) ? 1.0f : glm::clamp(
|
||||
return (forceRenderHead) ? 1.0f : glm::clamp(
|
||||
(distanceToCamera - DO_NOT_RENDER_INSIDE) / (RENDER_OPAQUE_OUTSIDE - DO_NOT_RENDER_INSIDE), 0.f, 1.f);
|
||||
}
|
||||
|
||||
void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
||||
void MyAvatar::renderBody(bool forceRenderHead, bool renderAvatarBalls) {
|
||||
|
||||
if (_head.getVideoFace().isFullFrame()) {
|
||||
// Render the full-frame video
|
||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
|
||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, forceRenderHead);
|
||||
if (alpha > 0.0f) {
|
||||
_head.getVideoFace().render(1.0f);
|
||||
}
|
||||
|
@ -644,7 +647,7 @@ void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
glm::vec3 skinColor, darkSkinColor;
|
||||
getSkinColors(skinColor, darkSkinColor);
|
||||
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||
float alpha = getBallRenderAlpha(b, lookingInMirror);
|
||||
float alpha = getBallRenderAlpha(b, forceRenderHead);
|
||||
|
||||
// When we have leap hands, hide part of the arms.
|
||||
if (_hand.getNumPalms() > 0) {
|
||||
|
@ -710,12 +713,12 @@ void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
if (!_skeletonModel.render(1.0f)) {
|
||||
_voxels.render(false);
|
||||
}
|
||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
|
||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, forceRenderHead);
|
||||
if (alpha > 0.0f) {
|
||||
_head.render(alpha, true);
|
||||
}
|
||||
}
|
||||
_hand.render(lookingInMirror);
|
||||
_hand.render();
|
||||
}
|
||||
|
||||
void MyAvatar::updateThrust(float deltaTime, Transmitter * transmitter) {
|
||||
|
@ -743,8 +746,7 @@ void MyAvatar::updateThrust(float deltaTime, Transmitter * transmitter) {
|
|||
_thrust -= _driveKeys[DOWN] * _scale * THRUST_MAG_DOWN * _thrustMultiplier * deltaTime * up;
|
||||
_bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_MAG * deltaTime;
|
||||
_bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_MAG * deltaTime;
|
||||
_mousePitchDelta = min(_mousePitchDelta + _driveKeys[ROT_UP] * PITCH_MAG * deltaTime, MAX_PITCH);
|
||||
_mousePitchDelta = max(_mousePitchDelta - _driveKeys[ROT_DOWN] * PITCH_MAG * deltaTime, -MAX_PITCH);
|
||||
_head.setMousePitch(_head.getMousePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_MAG * deltaTime);
|
||||
|
||||
// If thrust keys are being held down, slowly increase thrust to allow reaching great speeds
|
||||
if (_driveKeys[FWD] || _driveKeys[BACK] || _driveKeys[RIGHT] || _driveKeys[LEFT] || _driveKeys[UP] || _driveKeys[DOWN]) {
|
||||
|
@ -1271,7 +1273,3 @@ void MyAvatar::setOrientation(const glm::quat& orientation) {
|
|||
_bodyYaw = eulerAngles.y;
|
||||
_bodyRoll = eulerAngles.z;
|
||||
}
|
||||
|
||||
void MyAvatar::setNewScale(const float scale) {
|
||||
_newScale = scale;
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ public:
|
|||
|
||||
void reset();
|
||||
void simulate(float deltaTime, Transmitter* transmitter);
|
||||
void updateFromGyrosAndOrWebcam(float pitchFromTouch, bool turnWithHead);
|
||||
void render(bool lookingInMirror, bool renderAvatarBalls);
|
||||
void renderScreenTint(ScreenTintLayer layer, Camera& whichCamera);
|
||||
void updateFromGyrosAndOrWebcam(bool turnWithHead);
|
||||
void render(bool forceRenderHead, bool renderAvatarBalls);
|
||||
void renderScreenTint(ScreenTintLayer layer);
|
||||
|
||||
// setters
|
||||
void setMousePressed(bool mousePressed) { _mousePressed = mousePressed; }
|
||||
|
@ -30,12 +30,10 @@ public:
|
|||
void setLeanScale(float scale) { _leanScale = scale; }
|
||||
void setGravity(glm::vec3 gravity);
|
||||
void setOrientation(const glm::quat& orientation);
|
||||
void setNewScale(const float scale);
|
||||
void setWantCollisionsOn(bool wantCollisionsOn) { _isCollisionsOn = wantCollisionsOn; }
|
||||
void setMoveTarget(const glm::vec3 moveTarget);
|
||||
|
||||
// getters
|
||||
float getNewScale() const { return _newScale; }
|
||||
float getSpeed() const { return _speed; }
|
||||
AvatarMode getMode() const { return _mode; }
|
||||
float getLeanScale() const { return _leanScale; }
|
||||
|
@ -66,7 +64,6 @@ private:
|
|||
bool _mousePressed;
|
||||
float _bodyPitchDelta;
|
||||
float _bodyRollDelta;
|
||||
float _mousePitchDelta;
|
||||
bool _shouldJump;
|
||||
float _driveKeys[MAX_DRIVE_KEYS];
|
||||
glm::vec3 _gravity;
|
||||
|
@ -84,8 +81,8 @@ private:
|
|||
int _moveTargetStepCounter;
|
||||
|
||||
// private methods
|
||||
float getBallRenderAlpha(int ball, bool lookingInMirror) const;
|
||||
void renderBody(bool lookingInMirror, bool renderAvatarBalls);
|
||||
float getBallRenderAlpha(int ball, bool forceRenderHead) const;
|
||||
void renderBody(bool forceRenderHead, bool renderAvatarBalls);
|
||||
void updateThrust(float deltaTime, Transmitter * transmitter);
|
||||
void updateHandMovementAndTouching(float deltaTime, bool enableHandMovement);
|
||||
void updateAvatarCollisions(float deltaTime);
|
||||
|
|
|
@ -92,6 +92,17 @@ void Faceshift::reset() {
|
|||
_longTermAverageInitialized = false;
|
||||
}
|
||||
|
||||
void Faceshift::updateFakeCoefficients(float leftBlink, float rightBlink, float browUp,
|
||||
float jawOpen, std::vector<float>& coefficients) const {
|
||||
coefficients.resize(max((int)coefficients.size(), _jawOpenIndex + 1));
|
||||
coefficients[_leftBlinkIndex] = leftBlink;
|
||||
coefficients[_rightBlinkIndex] = rightBlink;
|
||||
coefficients[_browUpCenterIndex] = browUp;
|
||||
coefficients[_browUpLeftIndex] = browUp;
|
||||
coefficients[_browUpRightIndex] = browUp;
|
||||
coefficients[_jawOpenIndex] = jawOpen;
|
||||
}
|
||||
|
||||
void Faceshift::setTCPEnabled(bool enabled) {
|
||||
if ((_tcpEnabled = enabled)) {
|
||||
connectSocket();
|
||||
|
|
|
@ -62,6 +62,9 @@ public:
|
|||
void update();
|
||||
void reset();
|
||||
|
||||
void updateFakeCoefficients(float leftBlink, float rightBlink, float browUp,
|
||||
float jawOpen, std::vector<float>& coefficients) const;
|
||||
|
||||
public slots:
|
||||
|
||||
void setTCPEnabled(bool enabled);
|
||||
|
|
|
@ -271,7 +271,7 @@ void LeapManager::nextFrame() {
|
|||
hand.updateFingerTrails();
|
||||
|
||||
// if Leap drive is enabled, drive avatar based on Leap input
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::LeapDrive)) {
|
||||
if (!(Menu::getInstance()->isOptionChecked(MenuOption::LeapDrive) && gotRealData)) {
|
||||
return;
|
||||
}
|
||||
glm::vec3 relativePosition;
|
||||
|
|
|
@ -447,7 +447,7 @@ bool Model::render(float alpha) {
|
|||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// restore all the default material settings
|
||||
Application::getInstance()->setupWorldLight(*Application::getInstance()->getCamera());
|
||||
Application::getInstance()->setupWorldLight();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ TextureCache::TextureCache() :
|
|||
_blueTextureID(0),
|
||||
_primaryFramebufferObject(NULL),
|
||||
_secondaryFramebufferObject(NULL),
|
||||
_tertiaryFramebufferObject(NULL)
|
||||
_tertiaryFramebufferObject(NULL),
|
||||
_shadowFramebufferObject(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -179,6 +180,38 @@ QOpenGLFramebufferObject* TextureCache::getTertiaryFramebufferObject() {
|
|||
return _tertiaryFramebufferObject;
|
||||
}
|
||||
|
||||
QOpenGLFramebufferObject* TextureCache::getShadowFramebufferObject() {
|
||||
if (_shadowFramebufferObject == NULL) {
|
||||
const int SHADOW_MAP_SIZE = 2048;
|
||||
_shadowFramebufferObject = new QOpenGLFramebufferObject(SHADOW_MAP_SIZE, SHADOW_MAP_SIZE,
|
||||
QOpenGLFramebufferObject::NoAttachment, GL_TEXTURE_2D, GL_RGB);
|
||||
|
||||
glGenTextures(1, &_shadowDepthTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, _shadowDepthTextureID);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE,
|
||||
0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
const float DISTANT_BORDER[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, DISTANT_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
_shadowFramebufferObject->bind();
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _shadowDepthTextureID, 0);
|
||||
_shadowFramebufferObject->release();
|
||||
}
|
||||
return _shadowFramebufferObject;
|
||||
}
|
||||
|
||||
GLuint TextureCache::getShadowDepthTextureID() {
|
||||
// ensure that the shadow framebuffer object is initialized before returning the depth texture id
|
||||
getShadowFramebufferObject();
|
||||
return _shadowDepthTextureID;
|
||||
}
|
||||
|
||||
bool TextureCache::eventFilter(QObject* watched, QEvent* event) {
|
||||
if (event->type() == QEvent::Resize) {
|
||||
QSize size = static_cast<QResizeEvent*>(event)->size();
|
||||
|
|
|
@ -64,6 +64,12 @@ public:
|
|||
/// screen effects.
|
||||
QOpenGLFramebufferObject* getTertiaryFramebufferObject();
|
||||
|
||||
/// Returns a pointer to the framebuffer object used to render shadow maps.
|
||||
QOpenGLFramebufferObject* getShadowFramebufferObject();
|
||||
|
||||
/// Returns the ID of the shadow framebuffer object's depth texture.
|
||||
GLuint getShadowDepthTextureID();
|
||||
|
||||
virtual bool eventFilter(QObject* watched, QEvent* event);
|
||||
|
||||
private:
|
||||
|
@ -83,6 +89,9 @@ private:
|
|||
QOpenGLFramebufferObject* _primaryFramebufferObject;
|
||||
QOpenGLFramebufferObject* _secondaryFramebufferObject;
|
||||
QOpenGLFramebufferObject* _tertiaryFramebufferObject;
|
||||
|
||||
QOpenGLFramebufferObject* _shadowFramebufferObject;
|
||||
GLuint _shadowDepthTextureID;
|
||||
};
|
||||
|
||||
/// A simple object wrapper for an OpenGL texture.
|
||||
|
|
|
@ -75,6 +75,10 @@ public:
|
|||
float getBodyRoll() const { return _bodyRoll; }
|
||||
void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; }
|
||||
|
||||
// Scale
|
||||
float getNewScale() const { return _newScale; }
|
||||
void setNewScale(float newScale) { _newScale = newScale; }
|
||||
|
||||
// Hand State
|
||||
void setHandState(char s) { _handState = s; }
|
||||
char getHandState() const { return _handState; }
|
||||
|
|
|
@ -162,6 +162,10 @@ void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetDat
|
|||
processSTUNResponse(packetData, dataBytes);
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_KILL_NODE: {
|
||||
processKillNode(packetData, dataBytes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,6 +453,38 @@ void NodeList::processSTUNResponse(unsigned char* packetData, size_t dataBytes)
|
|||
}
|
||||
}
|
||||
|
||||
void NodeList::sendKillNode(const char* nodeTypes, int numNodeTypes) {
|
||||
unsigned char packet[MAX_PACKET_SIZE];
|
||||
unsigned char* packetPosition = packet;
|
||||
|
||||
packetPosition += populateTypeAndVersion(packetPosition, PACKET_TYPE_KILL_NODE);
|
||||
|
||||
QByteArray rfcUUID = _ownerUUID.toRfc4122();
|
||||
memcpy(packetPosition, rfcUUID.constData(), rfcUUID.size());
|
||||
packetPosition += rfcUUID.size();
|
||||
|
||||
broadcastToNodes(packet, packetPosition - packet, nodeTypes, numNodeTypes);
|
||||
}
|
||||
|
||||
void NodeList::processKillNode(unsigned char* packetData, size_t dataBytes) {
|
||||
// skip the header
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
packetData += numBytesPacketHeader;
|
||||
dataBytes -= numBytesPacketHeader;
|
||||
|
||||
// read the node id
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*)packetData, NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
packetData += NUM_BYTES_RFC4122_UUID;
|
||||
dataBytes -= NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
// make sure the node exists
|
||||
Node* node = nodeWithUUID(nodeUUID);
|
||||
if (node) {
|
||||
killNode(node, true);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeList::sendDomainServerCheckIn() {
|
||||
static bool printedDomainServerIP = false;
|
||||
|
||||
|
|
|
@ -109,6 +109,8 @@ public:
|
|||
|
||||
void pingPublicAndLocalSocketsForInactiveNode(Node* node) const;
|
||||
|
||||
void sendKillNode(const char* nodeTypes, int numNodeTypes);
|
||||
|
||||
Node* nodeWithAddress(sockaddr *senderAddress);
|
||||
Node* nodeWithUUID(const QUuid& nodeUUID);
|
||||
|
||||
|
@ -155,6 +157,8 @@ private:
|
|||
void sendSTUNRequest();
|
||||
void processSTUNResponse(unsigned char* packetData, size_t dataBytes);
|
||||
|
||||
void processKillNode(unsigned char* packetData, size_t dataBytes);
|
||||
|
||||
QString _domainHostname;
|
||||
QHostAddress _domainIP;
|
||||
unsigned short _domainPort;
|
||||
|
|
|
@ -18,6 +18,7 @@ const PACKET_TYPE PACKET_TYPE_STUN_RESPONSE = 1;
|
|||
const PACKET_TYPE PACKET_TYPE_DOMAIN = 'D';
|
||||
const PACKET_TYPE PACKET_TYPE_PING = 'P';
|
||||
const PACKET_TYPE PACKET_TYPE_PING_REPLY = 'R';
|
||||
const PACKET_TYPE PACKET_TYPE_KILL_NODE = 'K';
|
||||
const PACKET_TYPE PACKET_TYPE_HEAD_DATA = 'H';
|
||||
const PACKET_TYPE PACKET_TYPE_Z_COMMAND = 'Z';
|
||||
const PACKET_TYPE PACKET_TYPE_INJECT_AUDIO = 'I';
|
||||
|
|
Loading…
Reference in a new issue