mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 12:13:42 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into 321contact
Conflicts: interface/src/Application.cpp
This commit is contained in:
commit
65907a75a3
9 changed files with 615 additions and 105 deletions
164
interface/resources/shaders/point_size.vert
Normal file
164
interface/resources/shaders/point_size.vert
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
attribute float voxelSizeIn;
|
||||||
|
varying float voxelSize;
|
||||||
|
|
||||||
|
uniform float viewportWidth;
|
||||||
|
uniform float viewportHeight;
|
||||||
|
uniform vec3 cameraPosition;
|
||||||
|
|
||||||
|
// Bit codes for faces
|
||||||
|
const int NONE = 0;
|
||||||
|
const int RIGHT = 1;
|
||||||
|
const int LEFT = 2;
|
||||||
|
const int BOTTOM = 4;
|
||||||
|
const int BOTTOM_RIGHT = BOTTOM + RIGHT;
|
||||||
|
const int BOTTOM_LEFT = BOTTOM + LEFT;
|
||||||
|
const int TOP = 8;
|
||||||
|
const int TOP_RIGHT = TOP + RIGHT;
|
||||||
|
const int TOP_LEFT = TOP + LEFT;
|
||||||
|
const int NEAR = 16;
|
||||||
|
const int NEAR_RIGHT = NEAR + RIGHT;
|
||||||
|
const int NEAR_LEFT = NEAR + LEFT;
|
||||||
|
const int NEAR_BOTTOM = NEAR + BOTTOM;
|
||||||
|
const int NEAR_BOTTOM_RIGHT = NEAR + BOTTOM + RIGHT;
|
||||||
|
const int NEAR_BOTTOM_LEFT = NEAR + BOTTOM + LEFT;
|
||||||
|
const int NEAR_TOP = NEAR + TOP;
|
||||||
|
const int NEAR_TOP_RIGHT = NEAR + TOP + RIGHT;
|
||||||
|
const int NEAR_TOP_LEFT = NEAR + TOP + LEFT;
|
||||||
|
const int FAR = 32;
|
||||||
|
const int FAR_RIGHT = FAR + RIGHT;
|
||||||
|
const int FAR_LEFT = FAR + LEFT;
|
||||||
|
const int FAR_BOTTOM = FAR + BOTTOM;
|
||||||
|
const int FAR_BOTTOM_RIGHT = FAR + BOTTOM + RIGHT;
|
||||||
|
const int FAR_BOTTOM_LEFT = FAR + BOTTOM + LEFT;
|
||||||
|
const int FAR_TOP = FAR + TOP;
|
||||||
|
const int FAR_TOP_RIGHT = FAR + TOP + RIGHT;
|
||||||
|
const int FAR_TOP_LEFT = FAR + TOP + LEFT;
|
||||||
|
|
||||||
|
// If we know the position of the camera relative to the voxel, we can a priori know the vertices that make the visible hull
|
||||||
|
// polygon. This also tells us which two vertices are known to make the longest possible distance between any pair of these
|
||||||
|
// vertices for the projected polygon. This is a visibleFaces table based on this knowledge.
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// Note: the gl_Vertex in this case are in "world coordinates" meaning they've already been scaled to TREE_SCALE
|
||||||
|
// this is also true for voxelSizeIn.
|
||||||
|
vec4 bottomNearRight = gl_Vertex;
|
||||||
|
vec4 topFarLeft = (gl_Vertex + vec4(voxelSizeIn, voxelSizeIn, voxelSizeIn, 0.0));
|
||||||
|
|
||||||
|
int visibleFaces = NONE;
|
||||||
|
|
||||||
|
// In order to use our visibleFaces "table" (implemented as if statements) below, we need to encode the 6-bit code to
|
||||||
|
// orient camera relative to the 6 defining faces of the voxel. Based on camera position relative to the bottomNearRight
|
||||||
|
// corner and the topFarLeft corner, we can calculate which hull and therefore which two vertices are furthest apart
|
||||||
|
// linearly once projected
|
||||||
|
if (cameraPosition.x < bottomNearRight.x) {
|
||||||
|
visibleFaces += RIGHT;
|
||||||
|
}
|
||||||
|
if (cameraPosition.x > topFarLeft.x) {
|
||||||
|
visibleFaces += LEFT;
|
||||||
|
}
|
||||||
|
if (cameraPosition.y < bottomNearRight.y) {
|
||||||
|
visibleFaces += BOTTOM;
|
||||||
|
}
|
||||||
|
if (cameraPosition.y > topFarLeft.y) {
|
||||||
|
visibleFaces += TOP;
|
||||||
|
}
|
||||||
|
if (cameraPosition.z < bottomNearRight.z) {
|
||||||
|
visibleFaces += NEAR;
|
||||||
|
}
|
||||||
|
if (cameraPosition.z > topFarLeft.z) {
|
||||||
|
visibleFaces += FAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 cornerAdjustOne;
|
||||||
|
vec4 cornerAdjustTwo;
|
||||||
|
|
||||||
|
if (visibleFaces == RIGHT) {
|
||||||
|
cornerAdjustOne = vec4(0,0,0,0) * voxelSizeIn;
|
||||||
|
cornerAdjustTwo = vec4(0,1,1,0) * voxelSizeIn;
|
||||||
|
} else if (visibleFaces == LEFT) {
|
||||||
|
cornerAdjustOne = vec4(1,0,0,0) * voxelSizeIn;
|
||||||
|
cornerAdjustTwo = vec4(1,1,1,0) * voxelSizeIn;
|
||||||
|
} else if (visibleFaces == BOTTOM) {
|
||||||
|
cornerAdjustOne = vec4(0,0,0,0) * voxelSizeIn;
|
||||||
|
cornerAdjustTwo = vec4(1,0,1,0) * voxelSizeIn;
|
||||||
|
} else if (visibleFaces == TOP) {
|
||||||
|
cornerAdjustOne = vec4(0,1,0,0) * voxelSizeIn;
|
||||||
|
cornerAdjustTwo = vec4(1,1,1,0) * voxelSizeIn;
|
||||||
|
} else if (visibleFaces == NEAR) {
|
||||||
|
cornerAdjustOne = vec4(0,0,0,0) * voxelSizeIn;
|
||||||
|
cornerAdjustTwo = vec4(1,1,0,0) * voxelSizeIn;
|
||||||
|
} else if (visibleFaces == FAR) {
|
||||||
|
cornerAdjustOne = vec4(0,0,1,0) * voxelSizeIn;
|
||||||
|
cornerAdjustTwo = vec4(1,1,1,0) * voxelSizeIn;
|
||||||
|
} else if (visibleFaces == NEAR_BOTTOM_LEFT ||
|
||||||
|
visibleFaces == FAR_TOP ||
|
||||||
|
visibleFaces == FAR_TOP_RIGHT) {
|
||||||
|
cornerAdjustOne = vec4(0,1,0,0) * voxelSizeIn;
|
||||||
|
cornerAdjustTwo = vec4(1,0,1,0) * voxelSizeIn;
|
||||||
|
} else if (visibleFaces == FAR_TOP_LEFT ||
|
||||||
|
visibleFaces == NEAR_RIGHT ||
|
||||||
|
visibleFaces == NEAR_BOTTOM ||
|
||||||
|
visibleFaces == NEAR_BOTTOM_RIGHT) {
|
||||||
|
cornerAdjustOne = vec4(0,0,1,0) * voxelSizeIn;
|
||||||
|
cornerAdjustTwo = vec4(1,1,0,0) * voxelSizeIn;
|
||||||
|
} else if (visibleFaces == NEAR_TOP_RIGHT ||
|
||||||
|
visibleFaces == FAR_LEFT ||
|
||||||
|
visibleFaces == FAR_BOTTOM_LEFT ||
|
||||||
|
visibleFaces == BOTTOM_RIGHT ||
|
||||||
|
visibleFaces == TOP_LEFT) {
|
||||||
|
cornerAdjustOne = vec4(1,0,0,0) * voxelSizeIn;
|
||||||
|
cornerAdjustTwo = vec4(0,1,1,0) * voxelSizeIn;
|
||||||
|
|
||||||
|
// Everything else...
|
||||||
|
//} else if (visibleFaces == BOTTOM_LEFT ||
|
||||||
|
// visibleFaces == TOP_RIGHT ||
|
||||||
|
// visibleFaces == NEAR_LEFT ||
|
||||||
|
// visibleFaces == FAR_RIGHT ||
|
||||||
|
// visibleFaces == NEAR_TOP ||
|
||||||
|
// visibleFaces == NEAR_TOP_LEFT ||
|
||||||
|
// visibleFaces == FAR_BOTTOM ||
|
||||||
|
// visibleFaces == FAR_BOTTOM_RIGHT) {
|
||||||
|
} else {
|
||||||
|
cornerAdjustOne = vec4(0,0,0,0) * voxelSizeIn;
|
||||||
|
cornerAdjustTwo = vec4(1,1,1,0) * voxelSizeIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine our corners
|
||||||
|
vec4 cornerOne = gl_Vertex + cornerAdjustOne;
|
||||||
|
vec4 cornerTwo = gl_Vertex + cornerAdjustTwo;
|
||||||
|
|
||||||
|
// Find their model view projections
|
||||||
|
vec4 cornerOneMVP = gl_ModelViewProjectionMatrix * cornerOne;
|
||||||
|
vec4 cornerTwoMVP = gl_ModelViewProjectionMatrix * cornerTwo;
|
||||||
|
|
||||||
|
// Map to x, y screen coordinates
|
||||||
|
vec2 cornerOneScreen = vec2(cornerOneMVP.x / cornerOneMVP.w, cornerOneMVP.y / cornerOneMVP.w);
|
||||||
|
if (cornerOneMVP.w < 0) {
|
||||||
|
cornerOneScreen.x = -cornerOneScreen.x;
|
||||||
|
cornerOneScreen.y = -cornerOneScreen.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 cornerTwoScreen = vec2(cornerTwoMVP.x / cornerTwoMVP.w, cornerTwoMVP.y / cornerTwoMVP.w);
|
||||||
|
if (cornerTwoMVP.w < 0) {
|
||||||
|
cornerTwoScreen.x = -cornerTwoScreen.x;
|
||||||
|
cornerTwoScreen.y = -cornerTwoScreen.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the distance between them in pixels
|
||||||
|
float voxelScreenWidth = abs(cornerOneScreen.x - cornerTwoScreen.x) * viewportWidth / 2.0;
|
||||||
|
float voxelScreenHeight = abs(cornerOneScreen.y - cornerTwoScreen.y) * viewportHeight / 2.0;
|
||||||
|
float voxelScreenLength = sqrt(voxelScreenHeight * voxelScreenHeight + voxelScreenWidth * voxelScreenWidth);
|
||||||
|
|
||||||
|
// Find the center of the voxel
|
||||||
|
vec4 centerVertex = gl_Vertex;
|
||||||
|
float halfSizeIn = voxelSizeIn / 2;
|
||||||
|
centerVertex += vec4(halfSizeIn, halfSizeIn, halfSizeIn, 0.0);
|
||||||
|
vec4 center = gl_ModelViewProjectionMatrix * centerVertex;
|
||||||
|
|
||||||
|
// Finally place the point at the center of the voxel, with a size equal to the maximum screen length
|
||||||
|
gl_Position = center;
|
||||||
|
gl_PointSize = voxelScreenLength;
|
||||||
|
gl_FrontColor = gl_Color;
|
||||||
|
}
|
|
@ -144,6 +144,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
_packetsPerSecond(0),
|
_packetsPerSecond(0),
|
||||||
_bytesPerSecond(0),
|
_bytesPerSecond(0),
|
||||||
_bytesCount(0),
|
_bytesCount(0),
|
||||||
|
_recentMaxPackets(0),
|
||||||
|
_resetRecentMaxPacketsSoon(true),
|
||||||
_swatch(NULL),
|
_swatch(NULL),
|
||||||
_pasteMode(false)
|
_pasteMode(false)
|
||||||
{
|
{
|
||||||
|
@ -1304,7 +1306,10 @@ static glm::vec3 getFaceVector(BoxFace face) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::idle() {
|
void Application::idle() {
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
|
||||||
|
// details if we're in ExtraDebugging mode. However, the ::update() and it's subcomponents will show their timing
|
||||||
|
// details normally.
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::ExtraDebugging);
|
||||||
PerformanceWarning warn(showWarnings, "Application::idle()");
|
PerformanceWarning warn(showWarnings, "Application::idle()");
|
||||||
|
|
||||||
timeval check;
|
timeval check;
|
||||||
|
@ -1314,22 +1319,30 @@ void Application::idle() {
|
||||||
|
|
||||||
double timeSinceLastUpdate = diffclock(&_lastTimeUpdated, &check);
|
double timeSinceLastUpdate = diffclock(&_lastTimeUpdated, &check);
|
||||||
if (timeSinceLastUpdate > IDLE_SIMULATE_MSECS) {
|
if (timeSinceLastUpdate > IDLE_SIMULATE_MSECS) {
|
||||||
|
{
|
||||||
const float BIGGEST_DELTA_TIME_SECS = 0.25f;
|
PerformanceWarning warn(showWarnings, "Application::idle()... update()");
|
||||||
update(glm::clamp((float)timeSinceLastUpdate / 1000.f, 0.f, BIGGEST_DELTA_TIME_SECS));
|
const float BIGGEST_DELTA_TIME_SECS = 0.25f;
|
||||||
_glWidget->updateGL();
|
update(glm::clamp((float)timeSinceLastUpdate / 1000.f, 0.f, BIGGEST_DELTA_TIME_SECS));
|
||||||
_lastTimeUpdated = check;
|
|
||||||
_idleLoopStdev.addValue(timeSinceLastUpdate);
|
|
||||||
|
|
||||||
// Record standard deviation and reset counter if needed
|
|
||||||
const int STDEV_SAMPLES = 500;
|
|
||||||
if (_idleLoopStdev.getSamples() > STDEV_SAMPLES) {
|
|
||||||
_idleLoopMeasuredJitter = _idleLoopStdev.getStDev();
|
|
||||||
_idleLoopStdev.reset();
|
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::idle()... updateGL()");
|
||||||
|
_glWidget->updateGL();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::idle()... rest of it");
|
||||||
|
_lastTimeUpdated = check;
|
||||||
|
_idleLoopStdev.addValue(timeSinceLastUpdate);
|
||||||
|
|
||||||
|
// Record standard deviation and reset counter if needed
|
||||||
|
const int STDEV_SAMPLES = 500;
|
||||||
|
if (_idleLoopStdev.getSamples() > STDEV_SAMPLES) {
|
||||||
|
_idleLoopMeasuredJitter = _idleLoopStdev.getStDev();
|
||||||
|
_idleLoopStdev.reset();
|
||||||
|
}
|
||||||
|
|
||||||
// After finishing all of the above work, restart the idle timer, allowing 2ms to process events.
|
// After finishing all of the above work, restart the idle timer, allowing 2ms to process events.
|
||||||
idleTimer->start(2);
|
idleTimer->start(2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Application::terminate() {
|
void Application::terminate() {
|
||||||
|
@ -1665,6 +1678,7 @@ void Application::init() {
|
||||||
_glowEffect.init();
|
_glowEffect.init();
|
||||||
_ambientOcclusionEffect.init();
|
_ambientOcclusionEffect.init();
|
||||||
_voxelShader.init();
|
_voxelShader.init();
|
||||||
|
_pointShader.init();
|
||||||
|
|
||||||
_handControl.setScreenDimensions(_glWidget->width(), _glWidget->height());
|
_handControl.setScreenDimensions(_glWidget->width(), _glWidget->height());
|
||||||
|
|
||||||
|
@ -1775,6 +1789,8 @@ static QUuid DEFAULT_NODE_ID_REF;
|
||||||
|
|
||||||
void Application::updateLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
|
void Application::updateLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
|
||||||
glm::vec3& eyePosition) {
|
glm::vec3& eyePosition) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateLookatTargetAvatar()");
|
||||||
|
|
||||||
_lookatTargetAvatar = findLookatTargetAvatar(mouseRayOrigin, mouseRayDirection, eyePosition, DEFAULT_NODE_ID_REF);
|
_lookatTargetAvatar = findLookatTargetAvatar(mouseRayOrigin, mouseRayDirection, eyePosition, DEFAULT_NODE_ID_REF);
|
||||||
}
|
}
|
||||||
|
@ -1906,17 +1922,13 @@ void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::update(float deltaTime) {
|
void Application::updateMouseRay(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection) {
|
||||||
|
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::update()");
|
PerformanceWarning warn(showWarnings, "Application::updateMouseRay()");
|
||||||
|
|
||||||
// tell my avatar if the mouse is being pressed...
|
_viewFrustum.computePickRay(_mouseX / (float)_glWidget->width(), _mouseY / (float)_glWidget->height(),
|
||||||
_myAvatar.setMousePressed(_mousePressed);
|
mouseRayOrigin, mouseRayDirection);
|
||||||
|
|
||||||
// check what's under the mouse and update the mouse voxel
|
|
||||||
glm::vec3 mouseRayOrigin, mouseRayDirection;
|
|
||||||
_viewFrustum.computePickRay(_mouseX / (float)_glWidget->width(),
|
|
||||||
_mouseY / (float)_glWidget->height(), mouseRayOrigin, mouseRayDirection);
|
|
||||||
|
|
||||||
// adjust for mirroring
|
// adjust for mirroring
|
||||||
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
|
@ -1927,12 +1939,19 @@ void Application::update(float deltaTime) {
|
||||||
_viewFrustum.getRight() * glm::dot(_viewFrustum.getRight(), mouseRayDirection));
|
_viewFrustum.getRight() * glm::dot(_viewFrustum.getRight(), mouseRayDirection));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tell my avatar if the mouse is being pressed...
|
||||||
|
_myAvatar.setMousePressed(_mousePressed);
|
||||||
|
|
||||||
// tell my avatar the posiion and direction of the ray projected ino the world based on the mouse position
|
// tell my avatar the posiion and direction of the ray projected ino the world based on the mouse position
|
||||||
_myAvatar.setMouseRay(mouseRayOrigin, mouseRayDirection);
|
_myAvatar.setMouseRay(mouseRayOrigin, mouseRayDirection);
|
||||||
|
}
|
||||||
// Set where I am looking based on my mouse ray (so that other people can see)
|
|
||||||
glm::vec3 lookAtSpot;
|
|
||||||
|
|
||||||
|
void Application::updateFaceshift(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
|
||||||
|
glm::vec3& lookAtRayOrigin, glm::vec3& lookAtRayDirection) {
|
||||||
|
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateFaceshift()");
|
||||||
|
|
||||||
// Update faceshift
|
// Update faceshift
|
||||||
_faceshift.update();
|
_faceshift.update();
|
||||||
|
|
||||||
|
@ -1940,20 +1959,26 @@ void Application::update(float deltaTime) {
|
||||||
if (_faceshift.isActive()) {
|
if (_faceshift.isActive()) {
|
||||||
_myAvatar.getHead().setAngularVelocity(_faceshift.getHeadAngularVelocity());
|
_myAvatar.getHead().setAngularVelocity(_faceshift.getHeadAngularVelocity());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateLookatTargetAvatar(mouseRayOrigin, mouseRayDirection, lookAtSpot);
|
void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot, glm::vec3& lookAtRayOrigin,
|
||||||
|
glm::vec3& lookAtRayDirection) {
|
||||||
|
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateMyAvatarLookAtPosition()");
|
||||||
|
|
||||||
if (!_lookatTargetAvatar) {
|
if (!_lookatTargetAvatar) {
|
||||||
if (_isHoverVoxel) {
|
if (_isHoverVoxel) {
|
||||||
// Look at the hovered voxel
|
// Look at the hovered voxel
|
||||||
lookAtSpot = getMouseVoxelWorldCoordinates(_hoverVoxel);
|
lookAtSpot = getMouseVoxelWorldCoordinates(_hoverVoxel);
|
||||||
|
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
lookAtSpot = _myCamera.getPosition();
|
lookAtSpot = _myCamera.getPosition();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Just look in direction of the mouse ray
|
// Just look in direction of the mouse ray
|
||||||
const float FAR_AWAY_STARE = TREE_SCALE;
|
const float FAR_AWAY_STARE = TREE_SCALE;
|
||||||
lookAtSpot = mouseRayOrigin + mouseRayDirection * FAR_AWAY_STARE;
|
lookAtSpot = lookAtRayOrigin + lookAtRayDirection * FAR_AWAY_STARE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_faceshift.isActive()) {
|
if (_faceshift.isActive()) {
|
||||||
|
@ -1967,11 +1992,14 @@ void Application::update(float deltaTime) {
|
||||||
glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin);
|
glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin);
|
||||||
}
|
}
|
||||||
_myAvatar.getHead().setLookAtPosition(lookAtSpot);
|
_myAvatar.getHead().setLookAtPosition(lookAtSpot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
|
||||||
|
float& distance, BoxFace& face) {
|
||||||
|
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels()");
|
||||||
|
|
||||||
// Find the voxel we are hovering over, and respond if clicked
|
|
||||||
float distance;
|
|
||||||
BoxFace face;
|
|
||||||
|
|
||||||
// If we have clicked on a voxel, update it's color
|
// If we have clicked on a voxel, update it's color
|
||||||
if (_isHoverVoxelSounding) {
|
if (_isHoverVoxelSounding) {
|
||||||
VoxelNode* hoveredNode = _voxels.getVoxelAt(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s);
|
VoxelNode* hoveredNode = _voxels.getVoxelAt(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s);
|
||||||
|
@ -1993,23 +2021,38 @@ void Application::update(float deltaTime) {
|
||||||
} else {
|
} else {
|
||||||
// Check for a new hover voxel
|
// Check for a new hover voxel
|
||||||
glm::vec4 oldVoxel(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s);
|
glm::vec4 oldVoxel(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s);
|
||||||
_isHoverVoxel = _voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _hoverVoxel, distance, face);
|
// only do this work if MAKE_SOUND_ON_VOXEL_HOVER or MAKE_SOUND_ON_VOXEL_CLICK is enabled,
|
||||||
if (MAKE_SOUND_ON_VOXEL_HOVER && _isHoverVoxel && glm::vec4(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s) != oldVoxel) {
|
// and make sure the tree is not already busy... because otherwise you'll have to wait.
|
||||||
_hoverVoxelOriginalColor[0] = _hoverVoxel.red;
|
if (!_voxels.treeIsBusy()) {
|
||||||
_hoverVoxelOriginalColor[1] = _hoverVoxel.green;
|
{
|
||||||
_hoverVoxelOriginalColor[2] = _hoverVoxel.blue;
|
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()");
|
||||||
_hoverVoxelOriginalColor[3] = 1;
|
_isHoverVoxel = _voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _hoverVoxel, distance, face);
|
||||||
_audio.startCollisionSound(1.0, HOVER_VOXEL_FREQUENCY * _hoverVoxel.s * TREE_SCALE, 0.0, HOVER_VOXEL_DECAY);
|
}
|
||||||
_isHoverVoxelSounding = true;
|
if (MAKE_SOUND_ON_VOXEL_HOVER && _isHoverVoxel &&
|
||||||
|
glm::vec4(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s) != oldVoxel) {
|
||||||
|
|
||||||
|
_hoverVoxelOriginalColor[0] = _hoverVoxel.red;
|
||||||
|
_hoverVoxelOriginalColor[1] = _hoverVoxel.green;
|
||||||
|
_hoverVoxelOriginalColor[2] = _hoverVoxel.blue;
|
||||||
|
_hoverVoxelOriginalColor[3] = 1;
|
||||||
|
_audio.startCollisionSound(1.0, HOVER_VOXEL_FREQUENCY * _hoverVoxel.s * TREE_SCALE, 0.0, HOVER_VOXEL_DECAY);
|
||||||
|
_isHoverVoxelSounding = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
|
||||||
|
float& distance, BoxFace& face) {
|
||||||
|
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateMouseVoxels()");
|
||||||
|
|
||||||
_mouseVoxel.s = 0.0f;
|
_mouseVoxel.s = 0.0f;
|
||||||
if (Menu::getInstance()->isVoxelModeActionChecked() &&
|
if (Menu::getInstance()->isVoxelModeActionChecked() &&
|
||||||
(fabs(_myAvatar.getVelocity().x) +
|
(fabs(_myAvatar.getVelocity().x) +
|
||||||
fabs(_myAvatar.getVelocity().y) +
|
fabs(_myAvatar.getVelocity().y) +
|
||||||
fabs(_myAvatar.getVelocity().z)) / 3 < MAX_AVATAR_EDIT_VELOCITY) {
|
fabs(_myAvatar.getVelocity().z)) / 3 < MAX_AVATAR_EDIT_VELOCITY) {
|
||||||
PerformanceWarning warn(showWarnings, "Application::update()... findRayIntersection()");
|
|
||||||
|
|
||||||
if (_voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _mouseVoxel, distance, face)) {
|
if (_voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _mouseVoxel, distance, face)) {
|
||||||
if (distance < MAX_VOXEL_EDIT_DISTANCE) {
|
if (distance < MAX_VOXEL_EDIT_DISTANCE) {
|
||||||
|
@ -2078,12 +2121,17 @@ void Application::update(float deltaTime) {
|
||||||
_justEditedVoxel = false;
|
_justEditedVoxel = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateHandAndTouch(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateHandAndTouch()");
|
||||||
|
|
||||||
// walking triggers the handControl to stop
|
// walking triggers the handControl to stop
|
||||||
if (_myAvatar.getMode() == AVATAR_MODE_WALKING) {
|
if (_myAvatar.getMode() == AVATAR_MODE_WALKING) {
|
||||||
_handControl.stop();
|
_handControl.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update from Touch
|
// Update from Touch
|
||||||
if (_isTouchPressed) {
|
if (_isTouchPressed) {
|
||||||
float TOUCH_YAW_SCALE = -0.25f;
|
float TOUCH_YAW_SCALE = -0.25f;
|
||||||
|
@ -2094,19 +2142,29 @@ void Application::update(float deltaTime) {
|
||||||
_lastTouchAvgX = _touchAvgX;
|
_lastTouchAvgX = _touchAvgX;
|
||||||
_lastTouchAvgY = _touchAvgY;
|
_lastTouchAvgY = _touchAvgY;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Leap finger-sensing device
|
|
||||||
|
void Application::updateLeap(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateLeap()");
|
||||||
|
|
||||||
LeapManager::enableFakeFingers(Menu::getInstance()->isOptionChecked(MenuOption::SimulateLeapHand));
|
LeapManager::enableFakeFingers(Menu::getInstance()->isOptionChecked(MenuOption::SimulateLeapHand));
|
||||||
_myAvatar.getHand().setRaveGloveActive(Menu::getInstance()->isOptionChecked(MenuOption::TestRaveGlove));
|
_myAvatar.getHand().setRaveGloveActive(Menu::getInstance()->isOptionChecked(MenuOption::TestRaveGlove));
|
||||||
LeapManager::nextFrame(_myAvatar);
|
LeapManager::nextFrame(_myAvatar);
|
||||||
|
}
|
||||||
// Read serial port interface devices
|
|
||||||
|
void Application::updateSerialDevices(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateSerialDevices()");
|
||||||
|
|
||||||
if (_serialHeadSensor.isActive()) {
|
if (_serialHeadSensor.isActive()) {
|
||||||
_serialHeadSensor.readData(deltaTime);
|
_serialHeadSensor.readData(deltaTime);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
|
|
||||||
updateAvatar(deltaTime);
|
void Application::updateThreads(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateThreads()");
|
||||||
|
|
||||||
// read incoming packets from network
|
// read incoming packets from network
|
||||||
if (!_enableNetworkThread) {
|
if (!_enableNetworkThread) {
|
||||||
|
@ -2118,12 +2176,12 @@ void Application::update(float deltaTime) {
|
||||||
_voxelProcessor.threadRoutine();
|
_voxelProcessor.threadRoutine();
|
||||||
_voxelEditSender.threadRoutine();
|
_voxelEditSender.threadRoutine();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateMyAvatarSimulation(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateMyAvatarSimulation()");
|
||||||
|
|
||||||
|
|
||||||
//loop through all the other avatars and simulate them...
|
|
||||||
updateAvatars(deltaTime, mouseRayOrigin, mouseRayDirection);
|
|
||||||
|
|
||||||
// Simulate myself
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Gravity)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Gravity)) {
|
||||||
_myAvatar.setGravity(_environment.getGravity(_myAvatar.getPosition()));
|
_myAvatar.setGravity(_environment.getGravity(_myAvatar.getPosition()));
|
||||||
}
|
}
|
||||||
|
@ -2136,12 +2194,21 @@ void Application::update(float deltaTime) {
|
||||||
} else {
|
} else {
|
||||||
_myAvatar.simulate(deltaTime, NULL);
|
_myAvatar.simulate(deltaTime, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Simulate particle cloud movements
|
|
||||||
|
void Application::updateParticles(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateParticles()");
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::ParticleCloud)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::ParticleCloud)) {
|
||||||
_cloud.simulate(deltaTime);
|
_cloud.simulate(deltaTime);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateTransmitter(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateTransmitter()");
|
||||||
|
|
||||||
// no transmitter drive implies transmitter pick
|
// no transmitter drive implies transmitter pick
|
||||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _myTransmitter.isConnected()) {
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _myTransmitter.isConnected()) {
|
||||||
_transmitterPickStart = _myAvatar.getSkeleton().joint[AVATAR_JOINT_CHEST].position;
|
_transmitterPickStart = _myAvatar.getSkeleton().joint[AVATAR_JOINT_CHEST].position;
|
||||||
|
@ -2176,7 +2243,12 @@ void Application::update(float deltaTime) {
|
||||||
} else {
|
} else {
|
||||||
_transmitterPickStart = _transmitterPickEnd = glm::vec3();
|
_transmitterPickStart = _transmitterPickEnd = glm::vec3();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateCamera(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateCamera()");
|
||||||
|
|
||||||
if (!OculusManager::isConnected()) {
|
if (!OculusManager::isConnected()) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||||
if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
|
if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
|
||||||
|
@ -2211,7 +2283,12 @@ void Application::update(float deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateDialogs(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateDialogs()");
|
||||||
|
|
||||||
// Update bandwidth dialog, if any
|
// Update bandwidth dialog, if any
|
||||||
BandwidthDialog* bandwidthDialog = Menu::getInstance()->getBandwidthDialog();
|
BandwidthDialog* bandwidthDialog = Menu::getInstance()->getBandwidthDialog();
|
||||||
if (bandwidthDialog) {
|
if (bandwidthDialog) {
|
||||||
|
@ -2222,6 +2299,11 @@ void Application::update(float deltaTime) {
|
||||||
if (voxelStatsDialog) {
|
if (voxelStatsDialog) {
|
||||||
voxelStatsDialog->update();
|
voxelStatsDialog->update();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateAudio(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateAudio()");
|
||||||
|
|
||||||
// Update audio stats for procedural sounds
|
// Update audio stats for procedural sounds
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -2229,7 +2311,12 @@ void Application::update(float deltaTime) {
|
||||||
_audio.setLastVelocity(_myAvatar.getVelocity());
|
_audio.setLastVelocity(_myAvatar.getVelocity());
|
||||||
_audio.eventuallyAnalyzePing();
|
_audio.eventuallyAnalyzePing();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateCursor(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::updateCursor()");
|
||||||
|
|
||||||
// watch mouse position, if it hasn't moved, hide the cursor
|
// watch mouse position, if it hasn't moved, hide the cursor
|
||||||
bool underMouse = _glWidget->underMouse();
|
bool underMouse = _glWidget->underMouse();
|
||||||
if (!_mouseHidden) {
|
if (!_mouseHidden) {
|
||||||
|
@ -2250,6 +2337,43 @@ void Application::update(float deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::update(float deltaTime) {
|
||||||
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::update()");
|
||||||
|
|
||||||
|
// check what's under the mouse and update the mouse voxel
|
||||||
|
glm::vec3 mouseRayOrigin, mouseRayDirection;
|
||||||
|
updateMouseRay(deltaTime, mouseRayOrigin, mouseRayDirection);
|
||||||
|
|
||||||
|
// Set where I am looking based on my mouse ray (so that other people can see)
|
||||||
|
glm::vec3 lookAtSpot;
|
||||||
|
glm::vec3 lookAtRayOrigin = mouseRayOrigin, lookAtRayDirection = mouseRayDirection;
|
||||||
|
|
||||||
|
updateFaceshift(deltaTime, mouseRayOrigin, mouseRayDirection, lookAtRayOrigin, lookAtRayDirection);
|
||||||
|
updateLookatTargetAvatar(mouseRayOrigin, mouseRayDirection, lookAtSpot);
|
||||||
|
updateMyAvatarLookAtPosition(lookAtSpot, lookAtRayOrigin, lookAtRayDirection);
|
||||||
|
|
||||||
|
// Find the voxel we are hovering over, and respond if clicked
|
||||||
|
float distance;
|
||||||
|
BoxFace face;
|
||||||
|
|
||||||
|
updateHoverVoxels(deltaTime, mouseRayOrigin, mouseRayDirection, distance, face); // clicking on voxels and making sounds
|
||||||
|
updateMouseVoxels(deltaTime, mouseRayOrigin, mouseRayDirection, distance, face); // UI/UX related to voxels
|
||||||
|
updateHandAndTouch(deltaTime); // Update state for touch sensors
|
||||||
|
updateLeap(deltaTime); // Leap finger-sensing device
|
||||||
|
updateSerialDevices(deltaTime); // Read serial port interface devices
|
||||||
|
updateAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
|
||||||
|
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
|
||||||
|
updateAvatars(deltaTime, mouseRayOrigin, mouseRayDirection); //loop through all the other avatars and simulate them...
|
||||||
|
updateMyAvatarSimulation(deltaTime); // Simulate myself
|
||||||
|
updateParticles(deltaTime); // Simulate particle cloud movements
|
||||||
|
updateTransmitter(deltaTime); // transmitter drive or pick
|
||||||
|
updateCamera(deltaTime); // handle various camera tweaks like off axis projection
|
||||||
|
updateDialogs(deltaTime); // update various stats dialogs if present
|
||||||
|
updateAudio(deltaTime); // Update audio stats for procedural sounds
|
||||||
|
updateCursor(deltaTime); // Handle cursor updates
|
||||||
|
}
|
||||||
|
|
||||||
void Application::updateAvatar(float deltaTime) {
|
void Application::updateAvatar(float deltaTime) {
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::updateAvatar()");
|
PerformanceWarning warn(showWarnings, "Application::updateAvatar()");
|
||||||
|
@ -3256,6 +3380,8 @@ void Application::displayStats() {
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarStats);
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarStats);
|
||||||
|
|
||||||
|
|
||||||
|
QLocale locale(QLocale::English);
|
||||||
|
|
||||||
std::stringstream voxelStats;
|
std::stringstream voxelStats;
|
||||||
voxelStats.precision(4);
|
voxelStats.precision(4);
|
||||||
voxelStats << "Voxels " <<
|
voxelStats << "Voxels " <<
|
||||||
|
@ -3278,11 +3404,19 @@ void Application::displayStats() {
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
||||||
|
|
||||||
|
unsigned long localTotal = VoxelNode::getNodeCount();
|
||||||
|
unsigned long localInternal = VoxelNode::getInternalNodeCount();
|
||||||
|
unsigned long localLeaves = VoxelNode::getLeafNodeCount();
|
||||||
|
QString localTotalString = locale.toString((uint)localTotal); // consider adding: .rightJustified(10, ' ');
|
||||||
|
QString localInternalString = locale.toString((uint)localInternal);
|
||||||
|
QString localLeavesString = locale.toString((uint)localLeaves);
|
||||||
|
|
||||||
|
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
voxelStats <<
|
voxelStats <<
|
||||||
"Local Voxels Total: " << VoxelNode::getNodeCount() << ", " <<
|
"Local Voxels Total: " << localTotalString.toLocal8Bit().constData() << " / " <<
|
||||||
"Internal: " << VoxelNode::getInternalNodeCount() << " , " <<
|
"Internal: " << localInternalString.toLocal8Bit().constData() << " / " <<
|
||||||
"Leaves: " << VoxelNode::getLeafNodeCount() << "";
|
"Leaves: " << localLeavesString.toLocal8Bit().constData() << "";
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
||||||
|
|
||||||
|
@ -3309,6 +3443,29 @@ void Application::displayStats() {
|
||||||
voxelStats << "Sending Mode: " << voxelDetails;
|
voxelStats << "Sending Mode: " << voxelDetails;
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
||||||
|
|
||||||
|
voxelStats.str("");
|
||||||
|
int voxelPacketsToProcess = _voxelProcessor.packetsToProcessCount();
|
||||||
|
QString packetsString = locale.toString((int)voxelPacketsToProcess);
|
||||||
|
QString maxString = locale.toString((int)_recentMaxPackets);
|
||||||
|
|
||||||
|
voxelStats << "Voxel Packets to Process: " << packetsString.toLocal8Bit().constData()
|
||||||
|
<< " [Recent Max: " << maxString.toLocal8Bit().constData() << "]";
|
||||||
|
|
||||||
|
if (_resetRecentMaxPacketsSoon && voxelPacketsToProcess > 0) {
|
||||||
|
_recentMaxPackets = 0;
|
||||||
|
_resetRecentMaxPacketsSoon = false;
|
||||||
|
}
|
||||||
|
if (voxelPacketsToProcess == 0) {
|
||||||
|
_resetRecentMaxPacketsSoon = true;
|
||||||
|
} else {
|
||||||
|
if (voxelPacketsToProcess > _recentMaxPackets) {
|
||||||
|
_recentMaxPackets = voxelPacketsToProcess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
||||||
|
|
||||||
|
|
||||||
Node *avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
Node *avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||||
char avatarMixerStats[200];
|
char avatarMixerStats[200];
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include "renderer/GeometryCache.h"
|
#include "renderer/GeometryCache.h"
|
||||||
#include "renderer/GlowEffect.h"
|
#include "renderer/GlowEffect.h"
|
||||||
#include "renderer/VoxelShader.h"
|
#include "renderer/VoxelShader.h"
|
||||||
|
#include "renderer/PointShader.h"
|
||||||
#include "renderer/TextureCache.h"
|
#include "renderer/TextureCache.h"
|
||||||
#include "ui/BandwidthDialog.h"
|
#include "ui/BandwidthDialog.h"
|
||||||
#include "ui/ChatEntry.h"
|
#include "ui/ChatEntry.h"
|
||||||
|
@ -162,6 +163,9 @@ public:
|
||||||
virtual void domainChanged(QString domain);
|
virtual void domainChanged(QString domain);
|
||||||
|
|
||||||
VoxelShader& getVoxelShader() { return _voxelShader; }
|
VoxelShader& getVoxelShader() { return _voxelShader; }
|
||||||
|
PointShader& getPointShader() { return _pointShader; }
|
||||||
|
|
||||||
|
glm::vec2 getViewportDimensions() const{ return glm::vec2(_glWidget->width(),_glWidget->height()); }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data);
|
void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data);
|
||||||
|
@ -219,9 +223,30 @@ private:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void update(float deltaTime);
|
void update(float deltaTime);
|
||||||
|
|
||||||
|
// Various helper functions called during update()
|
||||||
|
void updateMouseRay(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection);
|
||||||
|
void updateFaceshift(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
|
||||||
|
glm::vec3& lookAtRayOrigin, glm::vec3& lookAtRayDirection);
|
||||||
|
void updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot, glm::vec3& lookAtRayOrigin, glm::vec3& lookAtRayDirection);
|
||||||
|
void updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
|
||||||
|
float& distance, BoxFace& face);
|
||||||
|
void updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
|
||||||
|
float& distance, BoxFace& face);
|
||||||
void updateLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
|
void updateLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
|
||||||
glm::vec3& eyePosition);
|
glm::vec3& eyePosition);
|
||||||
|
void updateHandAndTouch(float deltaTime);
|
||||||
|
void updateLeap(float deltaTime);
|
||||||
|
void updateSerialDevices(float deltaTime);
|
||||||
|
void updateThreads(float deltaTime);
|
||||||
|
void updateMyAvatarSimulation(float deltaTime);
|
||||||
|
void updateParticles(float deltaTime);
|
||||||
|
void updateTransmitter(float deltaTime);
|
||||||
|
void updateCamera(float deltaTime);
|
||||||
|
void updateDialogs(float deltaTime);
|
||||||
|
void updateAudio(float deltaTime);
|
||||||
|
void updateCursor(float deltaTime);
|
||||||
|
|
||||||
Avatar* findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
|
Avatar* findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
|
||||||
glm::vec3& eyePosition, QUuid &nodeUUID);
|
glm::vec3& eyePosition, QUuid &nodeUUID);
|
||||||
bool isLookingAtMyAvatar(Avatar* avatar);
|
bool isLookingAtMyAvatar(Avatar* avatar);
|
||||||
|
@ -383,6 +408,7 @@ private:
|
||||||
GlowEffect _glowEffect;
|
GlowEffect _glowEffect;
|
||||||
AmbientOcclusionEffect _ambientOcclusionEffect;
|
AmbientOcclusionEffect _ambientOcclusionEffect;
|
||||||
VoxelShader _voxelShader;
|
VoxelShader _voxelShader;
|
||||||
|
PointShader _pointShader;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
Audio _audio;
|
Audio _audio;
|
||||||
|
@ -402,6 +428,9 @@ private:
|
||||||
int _bytesPerSecond;
|
int _bytesPerSecond;
|
||||||
int _bytesCount;
|
int _bytesCount;
|
||||||
|
|
||||||
|
int _recentMaxPackets; // recent max incoming voxel packets to process
|
||||||
|
bool _resetRecentMaxPacketsSoon;
|
||||||
|
|
||||||
StDev _idleLoopStdev;
|
StDev _idleLoopStdev;
|
||||||
float _idleLoopMeasuredJitter;
|
float _idleLoopMeasuredJitter;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ void VoxelPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char*
|
||||||
"VoxelPacketProcessor::processPacket()");
|
"VoxelPacketProcessor::processPacket()");
|
||||||
|
|
||||||
const int WAY_BEHIND = 300;
|
const int WAY_BEHIND = 300;
|
||||||
if (packetsToProcessCount() > WAY_BEHIND && Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
|
if (packetsToProcessCount() > WAY_BEHIND && Menu::getInstance()->isOptionChecked(MenuOption::ExtraDebugging)) {
|
||||||
qDebug("VoxelPacketProcessor::processPacket() packets to process=%d\n", packetsToProcessCount());
|
qDebug("VoxelPacketProcessor::processPacket() packets to process=%d\n", packetsToProcessCount());
|
||||||
}
|
}
|
||||||
ssize_t messageLength = packetLength;
|
ssize_t messageLength = packetLength;
|
||||||
|
|
|
@ -110,6 +110,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels)
|
||||||
|
|
||||||
_culledOnce = false;
|
_culledOnce = false;
|
||||||
_inhideOutOfView = false;
|
_inhideOutOfView = false;
|
||||||
|
_treeIsBusy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::voxelDeleted(VoxelNode* node) {
|
void VoxelSystem::voxelDeleted(VoxelNode* node) {
|
||||||
|
@ -595,9 +596,9 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
"readBitstreamToTree()");
|
"readBitstreamToTree()");
|
||||||
// ask the VoxelTree to read the bitstream into the tree
|
// ask the VoxelTree to read the bitstream into the tree
|
||||||
ReadBitstreamToTreeParams args(WANT_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID());
|
ReadBitstreamToTreeParams args(WANT_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID());
|
||||||
pthread_mutex_lock(&_treeLock);
|
lockTree();
|
||||||
_tree->readBitstreamToTree(voxelData, numBytes - numBytesPacketHeader, args);
|
_tree->readBitstreamToTree(voxelData, numBytes - numBytesPacketHeader, args);
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PACKET_TYPE_VOXEL_DATA_MONOCHROME: {
|
case PACKET_TYPE_VOXEL_DATA_MONOCHROME: {
|
||||||
|
@ -605,9 +606,9 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
"readBitstreamToTree()");
|
"readBitstreamToTree()");
|
||||||
// ask the VoxelTree to read the MONOCHROME bitstream into the tree
|
// ask the VoxelTree to read the MONOCHROME bitstream into the tree
|
||||||
ReadBitstreamToTreeParams args(NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID());
|
ReadBitstreamToTreeParams args(NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID());
|
||||||
pthread_mutex_lock(&_treeLock);
|
lockTree();
|
||||||
_tree->readBitstreamToTree(voxelData, numBytes - numBytesPacketHeader, args);
|
_tree->readBitstreamToTree(voxelData, numBytes - numBytesPacketHeader, args);
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PACKET_TYPE_Z_COMMAND:
|
case PACKET_TYPE_Z_COMMAND:
|
||||||
|
@ -1002,7 +1003,9 @@ int VoxelSystem::updateNodeInArrays(VoxelNode* node, bool reuseIndex, bool force
|
||||||
// not render these Voxels. We need to think about ways to keep the entire scene intact but maybe lower quality
|
// not render these Voxels. We need to think about ways to keep the entire scene intact but maybe lower quality
|
||||||
// possibly shifting down to lower LOD or something. This debug message is to help identify, if/when/how this
|
// possibly shifting down to lower LOD or something. This debug message is to help identify, if/when/how this
|
||||||
// state actually occurs.
|
// state actually occurs.
|
||||||
qDebug("OHHHH NOOOOOO!!!! updateNodeInArrays() BAILING (_voxelsInWriteArrays >= _maxVoxels)\n");
|
if (Menu::getInstance()->isOptionChecked(MenuOption::ExtraDebugging)) {
|
||||||
|
qDebug("OHHHH NOOOOOO!!!! updateNodeInArrays() BAILING (_voxelsInWriteArrays >= _maxVoxels)\n");
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1257,13 +1260,27 @@ void VoxelSystem::render(bool texture) {
|
||||||
|
|
||||||
if (!_voxelsAsPoints) {
|
if (!_voxelsAsPoints) {
|
||||||
Application::getInstance()->getVoxelShader().begin();
|
Application::getInstance()->getVoxelShader().begin();
|
||||||
|
|
||||||
attributeLocation = Application::getInstance()->getVoxelShader().attributeLocation("voxelSizeIn");
|
attributeLocation = Application::getInstance()->getVoxelShader().attributeLocation("voxelSizeIn");
|
||||||
glEnableVertexAttribArray(attributeLocation);
|
glEnableVertexAttribArray(attributeLocation);
|
||||||
glVertexAttribPointer(attributeLocation, 1, GL_FLOAT, false, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(3*sizeof(float)));
|
glVertexAttribPointer(attributeLocation, 1, GL_FLOAT, false, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(3*sizeof(float)));
|
||||||
} else {
|
} else {
|
||||||
const float POINT_SIZE = 4.0;
|
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||||
glPointSize(POINT_SIZE);
|
|
||||||
|
glm::vec2 viewDimensions = Application::getInstance()->getViewportDimensions();
|
||||||
|
float viewportWidth = viewDimensions.x;
|
||||||
|
float viewportHeight = viewDimensions.y;
|
||||||
|
glm::vec3 cameraPosition = Application::getInstance()->getViewFrustum()->getPosition();
|
||||||
|
PointShader& pointShader = Application::getInstance()->getPointShader();
|
||||||
|
|
||||||
|
pointShader.begin();
|
||||||
|
|
||||||
|
pointShader.setUniformValue(pointShader.uniformLocation("viewportWidth"), viewportWidth);
|
||||||
|
pointShader.setUniformValue(pointShader.uniformLocation("viewportHeight"), viewportHeight);
|
||||||
|
pointShader.setUniformValue(pointShader.uniformLocation("cameraPosition"), cameraPosition);
|
||||||
|
|
||||||
|
attributeLocation = pointShader.attributeLocation("voxelSizeIn");
|
||||||
|
glEnableVertexAttribArray(attributeLocation);
|
||||||
|
glVertexAttribPointer(attributeLocation, 1, GL_FLOAT, false, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(3*sizeof(float)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1287,6 +1304,10 @@ void VoxelSystem::render(bool texture) {
|
||||||
if (!_voxelsAsPoints) {
|
if (!_voxelsAsPoints) {
|
||||||
Application::getInstance()->getVoxelShader().end();
|
Application::getInstance()->getVoxelShader().end();
|
||||||
glDisableVertexAttribArray(attributeLocation);
|
glDisableVertexAttribArray(attributeLocation);
|
||||||
|
} else {
|
||||||
|
Application::getInstance()->getPointShader().end();
|
||||||
|
glDisableVertexAttribArray(attributeLocation);
|
||||||
|
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PerformanceWarning warn(showWarnings, "render().. TRIANGLES...");
|
PerformanceWarning warn(showWarnings, "render().. TRIANGLES...");
|
||||||
|
@ -1387,9 +1408,9 @@ void VoxelSystem::removeScaleAndReleaseProgram(bool texture) {
|
||||||
int VoxelSystem::_nodeCount = 0;
|
int VoxelSystem::_nodeCount = 0;
|
||||||
|
|
||||||
void VoxelSystem::killLocalVoxels() {
|
void VoxelSystem::killLocalVoxels() {
|
||||||
pthread_mutex_lock(&_treeLock);
|
lockTree();
|
||||||
_tree->eraseAllVoxels();
|
_tree->eraseAllVoxels();
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
clearFreeBufferIndexes();
|
clearFreeBufferIndexes();
|
||||||
_voxelsInReadArrays = 0; // do we need to do this?
|
_voxelsInReadArrays = 0; // do we need to do this?
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
|
@ -1408,9 +1429,9 @@ bool VoxelSystem::clearAllNodesBufferIndexOperation(VoxelNode* node, void* extra
|
||||||
|
|
||||||
void VoxelSystem::clearAllNodesBufferIndex() {
|
void VoxelSystem::clearAllNodesBufferIndex() {
|
||||||
_nodeCount = 0;
|
_nodeCount = 0;
|
||||||
pthread_mutex_lock(&_treeLock);
|
lockTree();
|
||||||
_tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation);
|
_tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation);
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
|
||||||
qDebug("clearing buffer index of %d nodes\n", _nodeCount);
|
qDebug("clearing buffer index of %d nodes\n", _nodeCount);
|
||||||
}
|
}
|
||||||
|
@ -1864,7 +1885,7 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) {
|
||||||
_inhideOutOfView = true;
|
_inhideOutOfView = true;
|
||||||
|
|
||||||
bool showDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showDebugDetails, "hideOutOfView()", showDebugDetails);
|
PerformanceWarning warn(showDebugDetails, "hideOutOfView()");
|
||||||
bool widenFrustum = true;
|
bool widenFrustum = true;
|
||||||
|
|
||||||
// When using "delta" view frustums and only hide/show items that are in the difference
|
// When using "delta" view frustums and only hide/show items that are in the difference
|
||||||
|
@ -1898,9 +1919,9 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&_treeLock);
|
lockTree();
|
||||||
_tree->recurseTreeWithOperation(hideOutOfViewOperation,(void*)&args);
|
_tree->recurseTreeWithOperation(hideOutOfViewOperation,(void*)&args);
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
_lastCulledViewFrustum = args.thisViewFrustum; // save last stable
|
_lastCulledViewFrustum = args.thisViewFrustum; // save last stable
|
||||||
_culledOnce = true;
|
_culledOnce = true;
|
||||||
|
|
||||||
|
@ -1909,7 +1930,8 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) {
|
||||||
setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY);
|
setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showDebugDetails) {
|
bool extraDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::ExtraDebugging);
|
||||||
|
if (extraDebugDetails) {
|
||||||
qDebug("hideOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld\n",
|
qDebug("hideOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld\n",
|
||||||
args.nodesScanned, args.nodesRemoved, args.nodesInside,
|
args.nodesScanned, args.nodesRemoved, args.nodesInside,
|
||||||
args.nodesIntersect, args.nodesOutside
|
args.nodesIntersect, args.nodesOutside
|
||||||
|
@ -2088,10 +2110,10 @@ bool VoxelSystem::hideOutOfViewOperation(VoxelNode* node, void* extraData) {
|
||||||
|
|
||||||
bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
VoxelDetail& detail, float& distance, BoxFace& face) {
|
VoxelDetail& detail, float& distance, BoxFace& face) {
|
||||||
pthread_mutex_lock(&_treeLock);
|
lockTree();
|
||||||
VoxelNode* node;
|
VoxelNode* node;
|
||||||
if (!_tree->findRayIntersection(origin, direction, node, distance, face)) {
|
if (!_tree->findRayIntersection(origin, direction, node, distance, face)) {
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
detail.x = node->getCorner().x;
|
detail.x = node->getCorner().x;
|
||||||
|
@ -2101,21 +2123,21 @@ bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3&
|
||||||
detail.red = node->getColor()[0];
|
detail.red = node->getColor()[0];
|
||||||
detail.green = node->getColor()[1];
|
detail.green = node->getColor()[1];
|
||||||
detail.blue = node->getColor()[2];
|
detail.blue = node->getColor()[2];
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VoxelSystem::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) {
|
bool VoxelSystem::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) {
|
||||||
pthread_mutex_lock(&_treeLock);
|
lockTree();
|
||||||
bool result = _tree->findSpherePenetration(center, radius, penetration);
|
bool result = _tree->findSpherePenetration(center, radius, penetration);
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VoxelSystem::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) {
|
bool VoxelSystem::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) {
|
||||||
pthread_mutex_lock(&_treeLock);
|
lockTree();
|
||||||
bool result = _tree->findCapsulePenetration(start, end, radius, penetration);
|
bool result = _tree->findCapsulePenetration(start, end, radius, penetration);
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2289,9 +2311,9 @@ void VoxelSystem::collectStatsForTreesAndVBOs() {
|
||||||
|
|
||||||
|
|
||||||
void VoxelSystem::deleteVoxelAt(float x, float y, float z, float s) {
|
void VoxelSystem::deleteVoxelAt(float x, float y, float z, float s) {
|
||||||
pthread_mutex_lock(&_treeLock);
|
lockTree();
|
||||||
_tree->deleteVoxelAt(x, y, z, s);
|
_tree->deleteVoxelAt(x, y, z, s);
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
|
|
||||||
// redraw!
|
// redraw!
|
||||||
setupNewVoxelsForDrawing(); // do we even need to do this? Or will the next network receive kick in?
|
setupNewVoxelsForDrawing(); // do we even need to do this? Or will the next network receive kick in?
|
||||||
|
@ -2306,9 +2328,9 @@ void VoxelSystem::createVoxel(float x, float y, float z, float s,
|
||||||
unsigned char red, unsigned char green, unsigned char blue, bool destructive) {
|
unsigned char red, unsigned char green, unsigned char blue, bool destructive) {
|
||||||
|
|
||||||
//qDebug("VoxelSystem::createVoxel(%f,%f,%f,%f)\n",x,y,z,s);
|
//qDebug("VoxelSystem::createVoxel(%f,%f,%f,%f)\n",x,y,z,s);
|
||||||
pthread_mutex_lock(&_treeLock);
|
lockTree();
|
||||||
_tree->createVoxel(x, y, z, s, red, green, blue, destructive);
|
_tree->createVoxel(x, y, z, s, red, green, blue, destructive);
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
|
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
};
|
};
|
||||||
|
@ -2631,9 +2653,9 @@ void VoxelSystem::nodeKilled(Node* node) {
|
||||||
if (_voxelServerCount > 0) {
|
if (_voxelServerCount > 0) {
|
||||||
// Kill any voxels from the local tree that match this nodeID
|
// Kill any voxels from the local tree that match this nodeID
|
||||||
// commenting out for removal of 16 bit node IDs
|
// commenting out for removal of 16 bit node IDs
|
||||||
pthread_mutex_lock(&_treeLock);
|
lockTree();
|
||||||
_tree->recurseTreeWithOperation(killSourceVoxelsOperation, &nodeUUID);
|
_tree->recurseTreeWithOperation(killSourceVoxelsOperation, &nodeUUID);
|
||||||
pthread_mutex_unlock(&_treeLock);
|
unlockTree();
|
||||||
_tree->setDirtyBit();
|
_tree->setDirtyBit();
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
} else {
|
} else {
|
||||||
|
@ -2701,5 +2723,15 @@ unsigned long VoxelSystem::getVoxelMemoryUsageGPU() {
|
||||||
return (_initialMemoryUsageGPU - currentFreeMemory);
|
return (_initialMemoryUsageGPU - currentFreeMemory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::lockTree() {
|
||||||
|
pthread_mutex_lock(&_treeLock);
|
||||||
|
_treeIsBusy = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::unlockTree() {
|
||||||
|
_treeIsBusy = false;
|
||||||
|
pthread_mutex_unlock(&_treeLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,8 @@ public:
|
||||||
virtual void nodeKilled(Node* node);
|
virtual void nodeKilled(Node* node);
|
||||||
virtual void domainChanged(QString domain);
|
virtual void domainChanged(QString domain);
|
||||||
|
|
||||||
|
bool treeIsBusy() const { return _treeIsBusy; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void importSize(float x, float y, float z);
|
void importSize(float x, float y, float z);
|
||||||
void importProgress(int progress);
|
void importProgress(int progress);
|
||||||
|
@ -302,6 +304,10 @@ private:
|
||||||
bool _useFastVoxelPipeline;
|
bool _useFastVoxelPipeline;
|
||||||
|
|
||||||
bool _inhideOutOfView;
|
bool _inhideOutOfView;
|
||||||
|
bool _treeIsBusy; // is the tree mutex locked? if so, it's busy, and if you can avoid it, don't access the tree
|
||||||
|
|
||||||
|
void lockTree();
|
||||||
|
void unlockTree();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
77
interface/src/renderer/PointShader.cpp
Normal file
77
interface/src/renderer/PointShader.cpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
//
|
||||||
|
// PointShader.cpp
|
||||||
|
// interface
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 10/30/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
|
||||||
|
// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
|
||||||
|
#include "InterfaceConfig.h"
|
||||||
|
|
||||||
|
#include <QOpenGLFramebufferObject>
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
|
#include "PointShader.h"
|
||||||
|
#include "ProgramObject.h"
|
||||||
|
#include "RenderUtil.h"
|
||||||
|
|
||||||
|
PointShader::PointShader()
|
||||||
|
: _initialized(false)
|
||||||
|
{
|
||||||
|
_program = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PointShader::~PointShader() {
|
||||||
|
if (_initialized) {
|
||||||
|
delete _program;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgramObject* PointShader::createPointShaderProgram(const QString& name) {
|
||||||
|
ProgramObject* program = new ProgramObject();
|
||||||
|
program->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/" + name + ".vert" );
|
||||||
|
program->link();
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointShader::init() {
|
||||||
|
if (_initialized) {
|
||||||
|
qDebug("[ERROR] PointShader is already initialized.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switchToResourcesParentIfRequired();
|
||||||
|
_program = createPointShaderProgram("point_size");
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointShader::begin() {
|
||||||
|
_program->bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointShader::end() {
|
||||||
|
_program->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
int PointShader::attributeLocation(const char* name) const {
|
||||||
|
if (_program) {
|
||||||
|
return _program->attributeLocation(name);
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PointShader::uniformLocation(const char* name) const {
|
||||||
|
if (_program) {
|
||||||
|
return _program->uniformLocation(name);
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointShader::setUniformValue(int uniformLocation, float value) {
|
||||||
|
_program->setUniformValue(uniformLocation, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointShader::setUniformValue(int uniformLocation, const glm::vec3& value) {
|
||||||
|
_program->setUniformValue(uniformLocation, value.x, value.y, value.z);
|
||||||
|
}
|
45
interface/src/renderer/PointShader.h
Normal file
45
interface/src/renderer/PointShader.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
//
|
||||||
|
// PointShader.h
|
||||||
|
// interface
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 10/30/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __interface__PointShader__
|
||||||
|
#define __interface__PointShader__
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class ProgramObject;
|
||||||
|
|
||||||
|
/// A shader program that draws voxels as points with variable sizes
|
||||||
|
class PointShader : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
PointShader();
|
||||||
|
~PointShader();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
/// Starts using the voxel point shader program.
|
||||||
|
void begin();
|
||||||
|
|
||||||
|
/// Stops using the voxel point shader program.
|
||||||
|
void end();
|
||||||
|
|
||||||
|
/// Gets access to attributes from the shader program
|
||||||
|
int attributeLocation(const char* name) const;
|
||||||
|
int uniformLocation(const char* name) const;
|
||||||
|
void setUniformValue(int uniformLocation, float value);
|
||||||
|
void setUniformValue(int uniformLocation, const glm::vec3& value);
|
||||||
|
|
||||||
|
static ProgramObject* createPointShaderProgram(const QString& name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _initialized;
|
||||||
|
ProgramObject* _program;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* defined(__interface__PointShader__) */
|
|
@ -24,6 +24,12 @@ public:
|
||||||
/// \param ssize_t packetLength size of received data
|
/// \param ssize_t packetLength size of received data
|
||||||
/// \thread network receive thread
|
/// \thread network receive thread
|
||||||
void queueReceivedPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
void queueReceivedPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||||
|
|
||||||
|
/// Are there received packets waiting to be processed
|
||||||
|
bool hasPacketsToProcess() const { return _packets.size() > 0; }
|
||||||
|
|
||||||
|
/// How many received packets waiting are to be processed
|
||||||
|
int packetsToProcessCount() const { return _packets.size(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Callback for processing of recieved packets. Implement this to process the incoming packets.
|
/// Callback for processing of recieved packets. Implement this to process the incoming packets.
|
||||||
|
@ -36,12 +42,6 @@ protected:
|
||||||
/// Implements generic processing behavior for this thread.
|
/// Implements generic processing behavior for this thread.
|
||||||
virtual bool process();
|
virtual bool process();
|
||||||
|
|
||||||
/// Are there received packets waiting to be processed
|
|
||||||
bool hasPacketsToProcess() const { return _packets.size() > 0; }
|
|
||||||
|
|
||||||
/// How many received packets waiting are to be processed
|
|
||||||
int packetsToProcessCount() const { return _packets.size(); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::vector<NetworkPacket> _packets;
|
std::vector<NetworkPacket> _packets;
|
||||||
|
|
Loading…
Reference in a new issue