Merge branch 'master' of https://github.com/worklist/hifi into glow

This commit is contained in:
Andrzej Kapolka 2013-08-08 12:01:03 -07:00
commit cb89f05a39
25 changed files with 308 additions and 142 deletions

View file

@ -79,6 +79,11 @@ int main(int argc, const char* argv[]) {
printf("Local Domain MODE!\n"); printf("Local Domain MODE!\n");
nodeList->setDomainIPToLocalhost(); nodeList->setDomainIPToLocalhost();
} }
const char* domainIP = getCmdOption(argc, argv, "--domain");
if (domainIP) {
NodeList::getInstance()->setDomainHostname(domainIP);
}
ssize_t receivedBytes = 0; ssize_t receivedBytes = 0;

View file

@ -26,51 +26,74 @@ static unsigned char from_hex_digit(char digit) {
return (digit < 'A') ? digit - '0' : (digit - 'A') + 10; return (digit < 'A') ? digit - '0' : (digit - 'A') + 10;
} }
static void write_byte(unsigned char value) { static int write_byte(unsigned char value) {
char chars[] = { to_hex_digit(value / 16), to_hex_digit(value % 16) }; char chars[] = { to_hex_digit(value / 16), to_hex_digit(value % 16) };
write(ttyFileDescriptor, chars, 2); return write(ttyFileDescriptor, chars, 2) != 2;
} }
static unsigned char read_byte() { static int read_byte(unsigned char* value) {
char chars[2]; char chars[2];
read(ttyFileDescriptor, chars, 2); if (read(ttyFileDescriptor, chars, 2) != 2) {
return from_hex_digit(chars[0]) * 16 + from_hex_digit(chars[1]); return 1;
}
*value = from_hex_digit(chars[0]) * 16 + from_hex_digit(chars[1]);
return 0;
} }
int tty_i2c_write(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char const *data) { int tty_i2c_write(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char const *data) {
write(ttyFileDescriptor, "WR", 2); if (write(ttyFileDescriptor, "WR", 2) != 2) {
write_byte(slave_addr); return 1;
write_byte(reg_addr); }
if (write_byte(slave_addr)) {
return 1;
}
if (write_byte(reg_addr)) {
return 1;
}
int i; int i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
write_byte(data[i]); if (write_byte(data[i])) {
return 1;
}
}
if (write(ttyFileDescriptor, "\n", 1) != 1) {
return 1;
} }
write(ttyFileDescriptor, "\n", 1);
char response[8]; char response[8];
read(ttyFileDescriptor, response, 8); return read(ttyFileDescriptor, response, 8) != 8;
return 0;
} }
int tty_i2c_read(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char *data) { int tty_i2c_read(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char *data) {
write(ttyFileDescriptor, "RD", 2); if (write(ttyFileDescriptor, "RD", 2) != 2) {
write_byte(slave_addr); return 1;
write_byte(reg_addr); }
write_byte(length); if (write_byte(slave_addr)) {
write(ttyFileDescriptor, "\n", 1); return 1;
}
if (write_byte(reg_addr)) {
return 1;
}
if (write_byte(length)) {
return 1;
}
if (write(ttyFileDescriptor, "\n", 1) != 1) {
return 1;
}
char prefix[6]; char prefix[6];
read(ttyFileDescriptor, prefix, 6); if (read(ttyFileDescriptor, prefix, 6) != 6) {
return 1;
}
int i; int i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
data[i] = read_byte(); if (read_byte(data + i)) {
return 1;
}
} }
char suffix[2]; char suffix[2];
read(ttyFileDescriptor, suffix, 2); return read(ttyFileDescriptor, suffix, 2) != 2;
return 0;
} }
void tty_delay_ms(unsigned long num_ms) { void tty_delay_ms(unsigned long num_ms) {

View file

@ -439,7 +439,7 @@ void Application::paintGL() {
// myCamera is. But we also want to do meaningful camera transforms on OpenGL for the offset camera // myCamera is. But we also want to do meaningful camera transforms on OpenGL for the offset camera
Camera whichCamera = _myCamera; Camera whichCamera = _myCamera;
if (_viewFrustumFromOffset->isChecked() && _frustumOn->isChecked()) { if (_frustumOn->isChecked()) {
// set the camera to third-person view but offset so we can see the frustum // set the camera to third-person view but offset so we can see the frustum
_viewFrustumOffsetCamera.setTargetPosition(_myCamera.getTargetPosition()); _viewFrustumOffsetCamera.setTargetPosition(_myCamera.getTargetPosition());
@ -467,56 +467,49 @@ void Application::paintGL() {
_frameCount++; _frameCount++;
} }
void Application::resizeGL(int width, int height) { void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height) {
float aspectRatio = ((float)width/(float)height); // based on screen resize float aspectRatio = ((float)width/(float)height); // based on screen resize
// reset the camera FOV to our preference...
_myCamera.setFieldOfView(_horizontalFieldOfView);
// get the lens details from the current camera
Camera& camera = _viewFrustumFromOffset->isChecked() ? _viewFrustumOffsetCamera : _myCamera;
float nearClip = camera.getNearClip();
float farClip = camera.getFarClip();
float fov;
if (OculusManager::isConnected()) { if (OculusManager::isConnected()) {
// more magic numbers; see Oculus SDK docs, p. 32 // more magic numbers; see Oculus SDK docs, p. 32
camera.setAspectRatio(aspectRatio *= 0.5); camera.setAspectRatio(aspectRatio *= 0.5);
camera.setFieldOfView(fov = 2 * atan((0.0468 * _oculusDistortionScale) / 0.041) * (180 / PIf)); camera.setFieldOfView(2 * atan((0.0468 * _oculusDistortionScale) / 0.041) * (180 / PIf));
// resize the render texture
if (_oculusTextureID != 0) {
glBindTexture(GL_TEXTURE_2D, _oculusTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
} else { } else {
camera.setAspectRatio(aspectRatio); camera.setAspectRatio(aspectRatio);
camera.setFieldOfView(fov = _horizontalFieldOfView); camera.setFieldOfView(_fieldOfView);
}
}
void Application::resizeGL(int width, int height) {
resetCamerasOnResizeGL(_viewFrustumOffsetCamera, width, height);
resetCamerasOnResizeGL(_myCamera, width, height);
// resize the render texture
if (OculusManager::isConnected() && _oculusTextureID != 0) {
glBindTexture(GL_TEXTURE_2D, _oculusTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
} }
// Tell our viewFrustum about this change // Tell our viewFrustum about this change, using the application camera
_viewFrustum.setAspectRatio(aspectRatio); loadViewFrustum(_myCamera, _viewFrustum);
glViewport(0, 0, width, height); // shouldn't this account for the menu??? glViewport(0, 0, width, height); // shouldn't this account for the menu???
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
// XXXBHG - If we're in view frustum mode, then we need to do this little bit of hackery so that
// OpenGL won't clip our frustum rendering lines. This is a debug hack for sure! Basically, this makes
// the near clip a little bit closer (therefor you see more) and the far clip a little bit farther (also,
// to see more.)
if (_frustumOn->isChecked()) {
nearClip -= 0.01f;
farClip += 0.01f;
}
// On window reshape, we need to tell OpenGL about our new setting // On window reshape, we need to tell OpenGL about our new setting
float left, right, bottom, top, nearVal, farVal; float left, right, bottom, top, nearVal, farVal;
glm::vec4 nearClipPlane, farClipPlane; glm::vec4 nearClipPlane, farClipPlane;
loadViewFrustum(camera, _viewFrustum);
_viewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); _viewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
// If we're in Display Frustum mode, then we want to use the slightly adjust near/far clip values of the
// _viewFrustumOffsetCamera, so that we can see more of the application content in the application's frustum
if (_frustumOn->isChecked()) {
nearVal = _viewFrustumOffsetCamera.getNearClip();
farVal = _viewFrustumOffsetCamera.getFarClip();
}
glFrustum(left, right, bottom, top, nearVal, farVal); glFrustum(left, right, bottom, top, nearVal, farVal);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
@ -819,11 +812,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
_colorVoxelMode->trigger(); _colorVoxelMode->trigger();
break; break;
case Qt::Key_O: case Qt::Key_O:
if (isShifted) { _selectVoxelMode->trigger();
_viewFrustumFromOffset->trigger();
} else {
_selectVoxelMode->trigger();
}
break; break;
case Qt::Key_Slash: case Qt::Key_Slash:
_renderStatsOn->trigger(); _renderStatsOn->trigger();
@ -1295,11 +1284,11 @@ void Application::editPreferences() {
avatarURL->setMinimumWidth(QLINE_MINIMUM_WIDTH); avatarURL->setMinimumWidth(QLINE_MINIMUM_WIDTH);
form->addRow("Avatar URL:", avatarURL); form->addRow("Avatar URL:", avatarURL);
QSpinBox* horizontalFieldOfView = new QSpinBox(); QSpinBox* fieldOfView = new QSpinBox();
horizontalFieldOfView->setMaximum(180); fieldOfView->setMaximum(180);
horizontalFieldOfView->setMinimum(1); fieldOfView->setMinimum(1);
horizontalFieldOfView->setValue(_horizontalFieldOfView); fieldOfView->setValue(_fieldOfView);
form->addRow("Horizontal field of view (degrees):", horizontalFieldOfView); form->addRow("Vertical Field of View (Degrees):", fieldOfView);
QDoubleSpinBox* gyroCameraSensitivity = new QDoubleSpinBox(); QDoubleSpinBox* gyroCameraSensitivity = new QDoubleSpinBox();
gyroCameraSensitivity->setValue(_gyroCameraSensitivity); gyroCameraSensitivity->setValue(_gyroCameraSensitivity);
@ -1359,7 +1348,7 @@ void Application::editPreferences() {
if (!shouldDynamicallySetJitterBuffer()) { if (!shouldDynamicallySetJitterBuffer()) {
_audio.setJitterBufferSamples(_audioJitterBufferSamples); _audio.setJitterBufferSamples(_audioJitterBufferSamples);
} }
_horizontalFieldOfView = horizontalFieldOfView->value(); _fieldOfView = fieldOfView->value();
resizeGL(_glWidget->width(), _glWidget->height()); resizeGL(_glWidget->width(), _glWidget->height());
} }
@ -2060,8 +2049,6 @@ void Application::initMenu() {
QMenu* frustumMenu = debugMenu->addMenu("View Frustum Debugging Tools"); QMenu* frustumMenu = debugMenu->addMenu("View Frustum Debugging Tools");
(_frustumOn = frustumMenu->addAction("Display Frustum"))->setCheckable(true); (_frustumOn = frustumMenu->addAction("Display Frustum"))->setCheckable(true);
_frustumOn->setShortcut(Qt::SHIFT | Qt::Key_F); _frustumOn->setShortcut(Qt::SHIFT | Qt::Key_F);
(_viewFrustumFromOffset = frustumMenu->addAction(
"Use Offset Camera", this, SLOT(setFrustumOffset(bool)), Qt::SHIFT | Qt::Key_O))->setCheckable(true);
_frustumRenderModeAction = frustumMenu->addAction( _frustumRenderModeAction = frustumMenu->addAction(
"Render Mode", this, SLOT(cycleFrustumRenderMode()), Qt::SHIFT | Qt::Key_R); "Render Mode", this, SLOT(cycleFrustumRenderMode()), Qt::SHIFT | Qt::Key_R);
updateFrustumRenderModeAction(); updateFrustumRenderModeAction();
@ -2776,6 +2763,7 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
float fov = camera.getFieldOfView(); float fov = camera.getFieldOfView();
float nearClip = camera.getNearClip(); float nearClip = camera.getNearClip();
float farClip = camera.getFarClip(); float farClip = camera.getFarClip();
float aspectRatio = camera.getAspectRatio();
glm::quat rotation = camera.getRotation(); glm::quat rotation = camera.getRotation();
@ -2784,6 +2772,7 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
viewFrustum.setOrientation(rotation); viewFrustum.setOrientation(rotation);
// Also make sure it's got the correct lens details from the camera // Also make sure it's got the correct lens details from the camera
viewFrustum.setAspectRatio(aspectRatio);
viewFrustum.setFieldOfView(fov); viewFrustum.setFieldOfView(fov);
viewFrustum.setNearClip(nearClip); viewFrustum.setNearClip(nearClip);
viewFrustum.setFarClip(farClip); viewFrustum.setFarClip(farClip);
@ -2940,6 +2929,9 @@ void Application::displayOculus(Camera& whichCamera) {
glPopMatrix(); glPopMatrix();
} }
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(Camera& whichCamera) {
// Setup 3D lights (after the camera transform, so that they are positioned in world space) // Setup 3D lights (after the camera transform, so that they are positioned in world space)
@ -2954,10 +2946,9 @@ void Application::setupWorldLight(Camera& whichCamera) {
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color);
GLfloat diffuse_color[] = { 0.8, 0.7, 0.7 }; GLfloat diffuse_color[] = { 0.8, 0.7, 0.7 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color);
GLfloat specular_color[] = { 1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_SPECULAR, specular_color);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color); glLightfv(GL_LIGHT0, GL_SPECULAR, WHITE_SPECULAR_COLOR);
glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE_SPECULAR_COLOR);
glMateriali(GL_FRONT, GL_SHININESS, 96); glMateriali(GL_FRONT, GL_SHININESS, 96);
} }
@ -3035,6 +3026,9 @@ void Application::displaySide(Camera& whichCamera) {
glutSolidSphere(sphereRadius, 15, 15); glutSolidSphere(sphereRadius, 15, 15);
glPopMatrix(); glPopMatrix();
// disable specular lighting for ground and voxels
glMaterialfv(GL_FRONT, GL_SPECULAR, NO_SPECULAR_COLOR);
//draw a grid ground plane.... //draw a grid ground plane....
if (_renderGroundPlaneOn->isChecked()) { if (_renderGroundPlaneOn->isChecked()) {
// draw grass plane with fog // draw grass plane with fog
@ -3063,6 +3057,9 @@ void Application::displaySide(Camera& whichCamera) {
_voxels.render(_renderVoxelTextures->isChecked()); _voxels.render(_renderVoxelTextures->isChecked());
} }
// restore default, white specular
glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE_SPECULAR_COLOR);
// indicate what we'll be adding/removing in mouse mode, if anything // indicate what we'll be adding/removing in mouse mode, if anything
if (_mouseVoxel.s != 0) { if (_mouseVoxel.s != 0) {
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
@ -3110,16 +3107,14 @@ void Application::displaySide(Camera& whichCamera) {
} }
// Render my own Avatar // Render my own Avatar
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myAvatar.getHead().setLookAtPosition(_myCamera.getPosition());
_myAvatar.getHead().setLookAtPosition(_myCamera.getPosition()); }
} _myAvatar.render(_lookingInMirror->isChecked(), _renderAvatarBalls->isChecked());
_myAvatar.render(_lookingInMirror->isChecked(), _renderAvatarBalls->isChecked()); _myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked());
_myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked());
if (_renderLookatIndicatorOn->isChecked() && _isLookingAtOtherAvatar) { if (_renderLookatIndicatorOn->isChecked() && _isLookingAtOtherAvatar) {
renderLookatIndicator(_lookatOtherPosition, whichCamera); renderLookatIndicator(_lookatOtherPosition, whichCamera);
}
} }
} }
@ -3312,7 +3307,7 @@ void Application::displayStats() {
int statsVerticalOffset = 8; int statsVerticalOffset = 8;
char stats[200]; char stats[200];
sprintf(stats, "%3.0f FPS, %d Pkts/sec, %3.2f Mbps", sprintf(stats, "%3.0f FPS, %d Pkts/sec, %3.2f Mbps ",
_fps, _packetsPerSecond, (float)_bytesPerSecond * 8.f / 1000000.f); _fps, _packetsPerSecond, (float)_bytesPerSecond * 8.f / 1000000.f);
drawtext(10, statsVerticalOffset + 15, 0.10f, 0, 1.0, 0, stats); drawtext(10, statsVerticalOffset + 15, 0.10f, 0, 1.0, 0, stats);
@ -3343,11 +3338,16 @@ void Application::displayStats() {
pingVoxel = totalPingVoxel/voxelServerCount; pingVoxel = totalPingVoxel/voxelServerCount;
} }
char pingStats[200]; char pingStats[200];
sprintf(pingStats, "Ping audio/avatar/voxel: %d / %d / %d avg %d max ", pingAudio, pingAvatar, pingVoxel, pingVoxelMax); sprintf(pingStats, "Ping audio/avatar/voxel: %d / %d / %d avg %d max ", pingAudio, pingAvatar, pingVoxel, pingVoxelMax);
drawtext(10, statsVerticalOffset + 35, 0.10f, 0, 1.0, 0, pingStats); drawtext(10, statsVerticalOffset + 35, 0.10f, 0, 1.0, 0, pingStats);
} }
char avatarStats[200];
glm::vec3 avatarPos = _myAvatar.getPosition();
sprintf(avatarStats, "Avatar position: %.3f, %.3f, %.3f, yaw = %.2f", avatarPos.x, avatarPos.y, avatarPos.z, _myAvatar.getBodyYaw());
drawtext(10, statsVerticalOffset + 55, 0.10f, 0, 1.0, 0, avatarStats);
std::stringstream voxelStats; std::stringstream voxelStats;
voxelStats.precision(4); voxelStats.precision(4);
@ -3961,6 +3961,8 @@ void Application::nodeKilled(Node* node) {
// Add the jurisditionDetails object to the list of "fade outs" // Add the jurisditionDetails object to the list of "fade outs"
VoxelFade fade(VoxelFade::FADE_OUT, NODE_KILLED_RED, NODE_KILLED_GREEN, NODE_KILLED_BLUE); VoxelFade fade(VoxelFade::FADE_OUT, NODE_KILLED_RED, NODE_KILLED_GREEN, NODE_KILLED_BLUE);
fade.voxelDetails = jurisditionDetails; fade.voxelDetails = jurisditionDetails;
const float slightly_smaller = 0.99;
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
_voxelFades.push_back(fade); _voxelFades.push_back(fade);
} }
} }
@ -3990,6 +3992,8 @@ int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLeng
// Add the jurisditionDetails object to the list of "fade outs" // Add the jurisditionDetails object to the list of "fade outs"
VoxelFade fade(VoxelFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE); VoxelFade fade(VoxelFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE);
fade.voxelDetails = jurisditionDetails; fade.voxelDetails = jurisditionDetails;
const float slightly_smaller = 0.99;
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
_voxelFades.push_back(fade); _voxelFades.push_back(fade);
} }
// store jurisdiction details for later use // store jurisdiction details for later use
@ -4144,7 +4148,7 @@ void Application::loadSettings(QSettings* settings) {
_gyroCameraSensitivity = loadSetting(settings, "gyroCameraSensitivity", 0.5f); _gyroCameraSensitivity = loadSetting(settings, "gyroCameraSensitivity", 0.5f);
_audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0); _audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);
_horizontalFieldOfView = loadSetting(settings, "horizontalFieldOfView", HORIZONTAL_FIELD_OF_VIEW_DEGREES); _fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);
settings->beginGroup("View Frustum Offset Camera"); settings->beginGroup("View Frustum Offset Camera");
// in case settings is corrupt or missing loadSetting() will check for NaN // in case settings is corrupt or missing loadSetting() will check for NaN
@ -4168,7 +4172,7 @@ void Application::saveSettings(QSettings* settings) {
settings->setValue("gyroCameraSensitivity", _gyroCameraSensitivity); settings->setValue("gyroCameraSensitivity", _gyroCameraSensitivity);
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples); settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
settings->setValue("horizontalFieldOfView", _horizontalFieldOfView); settings->setValue("fieldOfView", _fieldOfView);
settings->beginGroup("View Frustum Offset Camera"); settings->beginGroup("View Frustum Offset Camera");
settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffsetYaw); settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffsetYaw);
settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffsetPitch); settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffsetPitch);

View file

@ -212,6 +212,7 @@ private slots:
void toggleFollowMode(); void toggleFollowMode();
private: private:
void resetCamerasOnResizeGL(Camera& camera, int width, int height);
static void controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes, static void controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes,
const char* nodeTypes, int numNodeTypes); const char* nodeTypes, int numNodeTypes);
@ -308,7 +309,6 @@ private:
QAction* _voxelPaintColor; // The color with which to paint voxels QAction* _voxelPaintColor; // The color with which to paint voxels
QAction* _destructiveAddVoxel; // when doing voxel editing do we want them to be destructive QAction* _destructiveAddVoxel; // when doing voxel editing do we want them to be destructive
QAction* _frustumOn; // Whether or not to display the debug view frustum QAction* _frustumOn; // Whether or not to display the debug view frustum
QAction* _viewFrustumFromOffset; // Whether or not to offset the view of the frustum
QAction* _fullScreenMode; // whether we are in full screen mode QAction* _fullScreenMode; // whether we are in full screen mode
QAction* _frustumRenderModeAction; QAction* _frustumRenderModeAction;
QAction* _settingsAutosave; // Whether settings are saved automatically QAction* _settingsAutosave; // Whether settings are saved automatically
@ -384,7 +384,7 @@ private:
int _audioJitterBufferSamples; // Number of extra samples to wait before starting audio playback int _audioJitterBufferSamples; // Number of extra samples to wait before starting audio playback
float _horizontalFieldOfView; // In Degrees, doesn't apply to HMD like Oculus float _fieldOfView; // In Degrees, doesn't apply to HMD like Oculus
HandControl _handControl; HandControl _handControl;

View file

@ -51,6 +51,7 @@ public:
void lowPassFilter(int16_t* inputBuffer); void lowPassFilter(int16_t* inputBuffer);
void startCollisionSound(float magnitude, float frequency, float noise, float duration); void startCollisionSound(float magnitude, float frequency, float noise, float duration);
float getCollisionSoundMagnitude() { return _collisionSoundMagnitude; }; float getCollisionSoundMagnitude() { return _collisionSoundMagnitude; };
int getSongFileBytes() { return _songFileBytes; } int getSongFileBytes() { return _songFileBytes; }

View file

@ -37,7 +37,8 @@ Camera::Camera() {
_linearModeShift = 0.0f; _linearModeShift = 0.0f;
_mode = CAMERA_MODE_THIRD_PERSON; _mode = CAMERA_MODE_THIRD_PERSON;
_tightness = 10.0f; // default _tightness = 10.0f; // default
_fieldOfView = HORIZONTAL_FIELD_OF_VIEW_DEGREES; _fieldOfView = DEFAULT_FIELD_OF_VIEW_DEGREES;
_aspectRatio = 16.f/9.f;
_nearClip = 0.08f; // default _nearClip = 0.08f; // default
_farClip = 50.0f * TREE_SCALE; // default _farClip = 50.0f * TREE_SCALE; // default
_upShift = 0.0f; _upShift = 0.0f;

View file

@ -11,7 +11,7 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
const float HORIZONTAL_FIELD_OF_VIEW_DEGREES = 90.0f; const float DEFAULT_FIELD_OF_VIEW_DEGREES = 90.0f;
enum CameraMode enum CameraMode
{ {

View file

@ -27,12 +27,14 @@ void PairingHandler::sendPairRequest() {
int localAddress = getLocalAddress(); int localAddress = getLocalAddress();
char pairPacket[24] = {}; char pairPacket[24] = {};
sprintf(pairPacket, "Find %d.%d.%d.%d:%d", sprintf(pairPacket, "Find %d.%d.%d.%d:%hu",
localAddress & 0xFF, localAddress & 0xFF,
(localAddress >> 8) & 0xFF, (localAddress >> 8) & 0xFF,
(localAddress >> 16) & 0xFF, (localAddress >> 16) & 0xFF,
(localAddress >> 24) & 0xFF, (localAddress >> 24) & 0xFF,
NODE_SOCKET_LISTEN_PORT); NodeList::getInstance()->getSocketListenPort());
qDebug("Sending pair packet: %s\n", pairPacket);
sockaddr_in pairingServerSocket; sockaddr_in pairingServerSocket;

View file

@ -17,6 +17,7 @@ const float DEFAULT_PARTICLE_AIR_FRICTION = 2.0f;
const float DEFAULT_PARTICLE_LIFESPAN = 1.0f; const float DEFAULT_PARTICLE_LIFESPAN = 1.0f;
const int DEFAULT_PARTICLE_SPHERE_RESOLUTION = 6; const int DEFAULT_PARTICLE_SPHERE_RESOLUTION = 6;
const float DEFAULT_EMITTER_RENDER_LENGTH = 0.2f; const float DEFAULT_EMITTER_RENDER_LENGTH = 0.2f;
const float DEFAULT_PARTICLE_CONNECT_DISTANCE = 0.03f;
ParticleSystem::ParticleSystem() { ParticleSystem::ParticleSystem() {
@ -41,7 +42,8 @@ ParticleSystem::ParticleSystem() {
e->currentParticle = 0; e->currentParticle = 0;
e->particleRenderStyle = PARTICLE_RENDER_STYLE_SPHERE; e->particleRenderStyle = PARTICLE_RENDER_STYLE_SPHERE;
e->numParticlesEmittedThisTime = 0; e->numParticlesEmittedThisTime = 0;
e->maxParticleConnectDistance = DEFAULT_PARTICLE_CONNECT_DISTANCE;
for (int lifeStage = 0; lifeStage < NUM_PARTICLE_LIFE_STAGES; lifeStage++) { for (int lifeStage = 0; lifeStage < NUM_PARTICLE_LIFE_STAGES; lifeStage++) {
setParticleAttributesToDefault(&_emitter[emitterIndex].particleAttributes[lifeStage]); setParticleAttributesToDefault(&_emitter[emitterIndex].particleAttributes[lifeStage]);
} }
@ -110,6 +112,7 @@ void ParticleSystem::updateEmitter(int emitterIndex, float deltaTime) {
void ParticleSystem::createParticle(int e, float timeFraction) { void ParticleSystem::createParticle(int e, float timeFraction) {
float maxConnectDistSqr = _emitter[e].maxParticleConnectDistance * _emitter[e].maxParticleConnectDistance;
for (unsigned int p = 0; p < MAX_PARTICLES; p++) { for (unsigned int p = 0; p < MAX_PARTICLES; p++) {
if (!_particle[p].alive) { if (!_particle[p].alive) {
@ -122,9 +125,14 @@ void ParticleSystem::createParticle(int e, float timeFraction) {
_particle[p].color = _emitter[e].particleAttributes[PARTICLE_LIFESTAGE_0].color; _particle[p].color = _emitter[e].particleAttributes[PARTICLE_LIFESTAGE_0].color;
_particle[p].previousParticle = NULL_PARTICLE; _particle[p].previousParticle = NULL_PARTICLE;
if (_particle[_emitter[e].currentParticle].alive) { Particle& prev = _particle[_emitter[e].currentParticle];
if (_particle[_emitter[e].currentParticle].emitterIndex == e) { if (prev.alive) {
_particle[p].previousParticle = _emitter[e].currentParticle; if (prev.emitterIndex == e) {
glm::vec3 diff = prev.position - _particle[p].position;
float sqrDist = glm::dot(diff, diff);
if (sqrDist < maxConnectDistSqr) {
_particle[p].previousParticle = _emitter[e].currentParticle;
}
} }
} }

View file

@ -122,6 +122,7 @@ private:
int currentParticle; // the index of the most recently-emitted particle int currentParticle; // the index of the most recently-emitted particle
ParticleAttributes particleAttributes[NUM_PARTICLE_LIFE_STAGES]; // the attributes of particles emitted from this emitter ParticleAttributes particleAttributes[NUM_PARTICLE_LIFE_STAGES]; // the attributes of particles emitted from this emitter
ParticleRenderStyle particleRenderStyle; ParticleRenderStyle particleRenderStyle;
float maxParticleConnectDistance; // past this, don't connect the particles.
}; };
glm::vec3 _upDirection; glm::vec3 _upDirection;

View file

@ -225,7 +225,12 @@ void SerialInterface::readData(float deltaTime) {
// ask the invensense for raw gyro data // ask the invensense for raw gyro data
short accelData[3]; short accelData[3];
mpu_get_accel_reg(accelData, 0); if (mpu_get_accel_reg(accelData, 0)) {
close(_serialDescriptor);
qDebug("Disconnected SerialUSB.\n");
_active = false;
return; // disconnected
}
const float LSB_TO_METERS_PER_SECOND2 = 1.f / 16384.f * GRAVITY_EARTH; const float LSB_TO_METERS_PER_SECOND2 = 1.f / 16384.f * GRAVITY_EARTH;
// From MPU-9150 register map, with setting on // From MPU-9150 register map, with setting on

View file

@ -31,7 +31,6 @@ const bool BALLS_ON = false;
const bool USING_AVATAR_GRAVITY = true; const bool USING_AVATAR_GRAVITY = true;
const glm::vec3 DEFAULT_UP_DIRECTION (0.0f, 1.0f, 0.0f); const glm::vec3 DEFAULT_UP_DIRECTION (0.0f, 1.0f, 0.0f);
const float YAW_MAG = 500.0; const float YAW_MAG = 500.0;
const float BODY_SPIN_FRICTION = 5.0;
const float MY_HAND_HOLDING_PULL = 0.2; const float MY_HAND_HOLDING_PULL = 0.2;
const float YOUR_HAND_HOLDING_PULL = 1.0; const float YOUR_HAND_HOLDING_PULL = 1.0;
const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f; const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f;
@ -637,8 +636,13 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter, float gyroCamer
if (_isCollisionsOn) { if (_isCollisionsOn) {
Camera* myCamera = Application::getInstance()->getCamera(); Camera* myCamera = Application::getInstance()->getCamera();
_collisionRadius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cos(myCamera->getFieldOfView() / 2.f));
_collisionRadius *= COLLISION_RADIUS_SCALAR; if (myCamera->getMode() == CAMERA_MODE_FIRST_PERSON) {
_collisionRadius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cos(myCamera->getFieldOfView() / 2.f));
_collisionRadius *= COLLISION_RADIUS_SCALAR;
} else {
_collisionRadius = _height * .125f;
}
updateCollisionWithEnvironment(deltaTime); updateCollisionWithEnvironment(deltaTime);
updateCollisionWithVoxels(deltaTime); updateCollisionWithVoxels(deltaTime);
@ -665,12 +669,19 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter, float gyroCamer
orientation = orientation * glm::quat(glm::radians( orientation = orientation * glm::quat(glm::radians(
glm::vec3(_bodyPitchDelta, _bodyYawDelta, _bodyRollDelta) * deltaTime)); glm::vec3(_bodyPitchDelta, _bodyYawDelta, _bodyRollDelta) * deltaTime));
// decay body rotation momentum // decay body rotation momentum
const float BODY_SPIN_FRICTION = 7.5f;
float bodySpinMomentum = 1.0 - BODY_SPIN_FRICTION * deltaTime; float bodySpinMomentum = 1.0 - BODY_SPIN_FRICTION * deltaTime;
if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; } if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; }
_bodyPitchDelta *= bodySpinMomentum; _bodyPitchDelta *= bodySpinMomentum;
_bodyYawDelta *= bodySpinMomentum; _bodyYawDelta *= bodySpinMomentum;
_bodyRollDelta *= bodySpinMomentum; _bodyRollDelta *= bodySpinMomentum;
float MINIMUM_ROTATION_RATE = 2.0f;
if (fabs(_bodyYawDelta) < MINIMUM_ROTATION_RATE) { _bodyYawDelta = 0.f; }
if (fabs(_bodyRollDelta) < MINIMUM_ROTATION_RATE) { _bodyRollDelta = 0.f; }
if (fabs(_bodyPitchDelta) < MINIMUM_ROTATION_RATE) { _bodyPitchDelta = 0.f; }
const float MAX_STATIC_FRICTION_VELOCITY = 0.5f; const float MAX_STATIC_FRICTION_VELOCITY = 0.5f;
const float STATIC_FRICTION_STRENGTH = _scale * 20.f; const float STATIC_FRICTION_STRENGTH = _scale * 20.f;
applyStaticFriction(deltaTime, _velocity, MAX_STATIC_FRICTION_VELOCITY, STATIC_FRICTION_STRENGTH); applyStaticFriction(deltaTime, _velocity, MAX_STATIC_FRICTION_VELOCITY, STATIC_FRICTION_STRENGTH);
@ -991,7 +1002,7 @@ void Avatar::updateCollisionWithEnvironment(float deltaTime) {
glm::vec3 penetration; glm::vec3 penetration;
if (Application::getInstance()->getEnvironment()->findCapsulePenetration( if (Application::getInstance()->getEnvironment()->findCapsulePenetration(
_position - up * (_pelvisFloatingHeight - radius), _position - up * (_pelvisFloatingHeight - radius),
_position + up * (_height - _pelvisFloatingHeight - radius), radius, penetration)) { _position + up * (_height - _pelvisFloatingHeight + radius), radius, penetration)) {
_lastCollisionPosition = _position; _lastCollisionPosition = _position;
updateCollisionSound(penetration, deltaTime, ENVIRONMENT_COLLISION_FREQUENCY); updateCollisionSound(penetration, deltaTime, ENVIRONMENT_COLLISION_FREQUENCY);
applyHardCollision(penetration, ENVIRONMENT_SURFACE_ELASTICITY, ENVIRONMENT_SURFACE_DAMPING); applyHardCollision(penetration, ENVIRONMENT_SURFACE_ELASTICITY, ENVIRONMENT_SURFACE_DAMPING);
@ -1007,7 +1018,7 @@ void Avatar::updateCollisionWithVoxels(float deltaTime) {
glm::vec3 penetration; glm::vec3 penetration;
if (Application::getInstance()->getVoxels()->findCapsulePenetration( if (Application::getInstance()->getVoxels()->findCapsulePenetration(
_position - glm::vec3(0.0f, _pelvisFloatingHeight - radius, 0.0f), _position - glm::vec3(0.0f, _pelvisFloatingHeight - radius, 0.0f),
_position + glm::vec3(0.0f, _height - _pelvisFloatingHeight - radius, 0.0f), radius, penetration)) { _position + glm::vec3(0.0f, _height - _pelvisFloatingHeight + radius, 0.0f), radius, penetration)) {
_lastCollisionPosition = _position; _lastCollisionPosition = _position;
updateCollisionSound(penetration, deltaTime, VOXEL_COLLISION_FREQUENCY); updateCollisionSound(penetration, deltaTime, VOXEL_COLLISION_FREQUENCY);
applyHardCollision(penetration, VOXEL_ELASTICITY, VOXEL_DAMPING); applyHardCollision(penetration, VOXEL_ELASTICITY, VOXEL_DAMPING);
@ -1422,7 +1433,9 @@ float Avatar::getBallRenderAlpha(int ball, bool lookingInMirror) const {
void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) { void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
if (_head.getFace().isFullFrame()) { if (isMyAvatar() && Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON) {
// Dont display body
} else if (_head.getFace().isFullFrame()) {
// Render the full-frame video // Render the full-frame video
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror); float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
if (alpha > 0.0f) { if (alpha > 0.0f) {

View file

@ -63,7 +63,6 @@ void Face::setFrameFromWebcam() {
_textureSize = webcam->getTextureSize(); _textureSize = webcam->getTextureSize();
_textureRect = webcam->getFaceRect(); _textureRect = webcam->getFaceRect();
_aspectRatio = webcam->getAspectRatio(); _aspectRatio = webcam->getAspectRatio();
} else { } else {
clearFrame(); clearFrame();
} }
@ -262,6 +261,12 @@ bool Face::render(float alpha) {
xScale = FULL_FRAME_SCALE * _owningHead->getScale(); xScale = FULL_FRAME_SCALE * _owningHead->getScale();
zScale = xScale * 0.3f; zScale = xScale * 0.3f;
glPushMatrix();
glTranslatef(0.0f, -0.2f, 0.0f);
glScalef(0.5f * xScale, xScale / aspect, zScale);
glColor4f(1.0f, 1.0f, 1.0f, alpha);
Application::getInstance()->getGeometryCache()->renderHalfCylinder(25, 20);
glPopMatrix();
} else { } else {
aspect = _aspectRatio; aspect = _aspectRatio;
xScale = BODY_BALL_RADIUS_HEAD_BASE * _owningHead->getScale(); xScale = BODY_BALL_RADIUS_HEAD_BASE * _owningHead->getScale();
@ -308,7 +313,7 @@ bool Face::render(float alpha) {
glGenBuffers(1, &_iboID); glGenBuffers(1, &_iboID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iboID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iboID);
int* indices = new int[INDEX_COUNT]; int* indices = new int[INDEX_COUNT];
int* indexPosition = indices; int* indexPosition = indices;
for (int i = 0; i < QUAD_HEIGHT; i++) { for (int i = 0; i < QUAD_HEIGHT; i++) {
for (int j = 0; j < QUAD_WIDTH; j++) { for (int j = 0; j < QUAD_WIDTH; j++) {
*indexPosition++ = i * VERTEX_WIDTH + j; *indexPosition++ = i * VERTEX_WIDTH + j;

View file

@ -61,7 +61,7 @@ private:
cv::Size2f _textureSize; cv::Size2f _textureSize;
cv::RotatedRect _textureRect; cv::RotatedRect _textureRect;
float _aspectRatio; float _aspectRatio;
vpx_codec_ctx_t _colorCodec; vpx_codec_ctx_t _colorCodec;
vpx_codec_ctx_t _depthCodec; vpx_codec_ctx_t _depthCodec;
bool _lastFullFrame; bool _lastFullFrame;

View file

@ -230,6 +230,8 @@ void Hand::renderLeapHands() {
//const glm::vec3 handColor = _ballColor; //const glm::vec3 handColor = _ballColor;
const glm::vec3 handColor(1.0, 0.84, 0.66); // use the skin color const glm::vec3 handColor(1.0, 0.84, 0.66); // use the skin color
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glPushMatrix(); glPushMatrix();
// Draw the leap balls // Draw the leap balls
for (size_t i = 0; i < _leapFingerTipBalls.size(); i++) { for (size_t i = 0; i < _leapFingerTipBalls.size(); i++) {
@ -270,29 +272,33 @@ void Hand::renderLeapHands() {
Avatar::renderJointConnectingCone(root, tip, 0.05, 0.03); Avatar::renderJointConnectingCone(root, tip, 0.05, 0.03);
} }
} }
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glPopMatrix(); glPopMatrix();
} }
void Hand::renderLeapFingerTrails() { void Hand::renderLeapFingerTrails() {
// Draw the finger root cones // Draw the finger root cones
glDisable(GL_LIGHTING);
for (size_t i = 0; i < getNumPalms(); ++i) { for (size_t i = 0; i < getNumPalms(); ++i) {
PalmData& palm = getPalms()[i]; PalmData& palm = getPalms()[i];
if (palm.isActive()) { if (palm.isActive()) {
for (size_t f = 0; f < palm.getNumFingers(); ++f) { for (size_t f = 0; f < palm.getNumFingers(); ++f) {
FingerData& finger = palm.getFingers()[f]; FingerData& finger = palm.getFingers()[f];
int numPositions = finger.getTrailNumPositions(); int numPositions = finger.getTrailNumPositions() - 1;
if (numPositions > 0) { if (numPositions > 0) {
glBegin(GL_TRIANGLE_STRIP); glBegin(GL_TRIANGLE_STRIP);
for (int t = 0; t < numPositions; ++t) for (int t = 0; t < numPositions; ++t)
{ {
const glm::vec3& center = finger.getTrailPosition(t); const glm::vec3& center = finger.getTrailPosition(t);
const float halfWidth = 0.001f; const float halfWidth = 0.004f;
const glm::vec3 edgeDirection(1.0f, 0.0f, 0.0f); const glm::vec3 edgeDirection(1.0f, 0.0f, 0.0f);
glm::vec3 edge0 = center + edgeDirection * halfWidth; glm::vec3 edge0 = center + edgeDirection * halfWidth;
glm::vec3 edge1 = center - edgeDirection * halfWidth; glm::vec3 edge1 = center - edgeDirection * halfWidth;
float alpha = 1.0f - ((float)t / (float)(numPositions - 1)); float alpha = 1.0f - ((float)t / (float)(numPositions - 1));
glColor4f(1.0f, 0.0f, 0.0f, alpha); alpha *= 0.25f;
glColor4f(1.0f, 1.0f, 1.0f, alpha);
glVertex3fv((float*)&edge0); glVertex3fv((float*)&edge0);
glVertex3fv((float*)&edge1); glVertex3fv((float*)&edge1);
} }
@ -301,6 +307,7 @@ void Hand::renderLeapFingerTrails() {
} }
} }
} }
glEnable(GL_LIGHTING);
} }
@ -322,25 +329,35 @@ void Hand::setLeapHands(const std::vector<glm::vec3>& handPositions,
// call this soon after the geometry of the leap hands are set // call this soon after the geometry of the leap hands are set
void Hand::updateRaveGloveEmitters() { void Hand::updateRaveGloveEmitters() {
int emitterIndex = 0;
for (size_t i = 0; i < NUM_FINGERS; i++) { for (size_t i = 0; i < NUM_FINGERS; i++) {
_raveGloveParticleSystem.setEmitterActive(_raveGloveEmitter[i], false); _raveGloveParticleSystem.setEmitterActive(_raveGloveEmitter[i], false);
} }
for (size_t i = 0; i < _leapFingerTipBalls.size(); i++) { for (size_t palmIndex = 0; palmIndex < getNumPalms(); ++palmIndex) {
if (i < NUM_FINGERS) { PalmData& palm = getPalms()[palmIndex];
glm::vec3 fingerDirection = _leapFingerTipBalls[i].position - _leapFingerRootBalls[i].position; if (palm.isActive()) {
float fingerLength = glm::length(fingerDirection); for (size_t f = 0; f < palm.getNumFingers(); ++f) {
FingerData& finger = palm.getFingers()[f];
if (fingerLength > 0.0f) { if (finger.isActive()) {
fingerDirection /= fingerLength; if (emitterIndex < NUM_FINGERS) { // safety, stop at the array size
} else { glm::vec3 fingerDirection = finger.getTipPosition() - finger.getRootPosition();
fingerDirection = IDENTITY_UP; float fingerLength = glm::length(fingerDirection);
if (fingerLength > 0.0f) {
fingerDirection /= fingerLength;
} else {
fingerDirection = IDENTITY_UP;
}
_raveGloveParticleSystem.setEmitterActive (_raveGloveEmitter[emitterIndex], true);
_raveGloveParticleSystem.setEmitterPosition (_raveGloveEmitter[emitterIndex], finger.getTipPosition());
_raveGloveParticleSystem.setEmitterDirection(_raveGloveEmitter[emitterIndex], fingerDirection);
}
}
emitterIndex++;
} }
_raveGloveParticleSystem.setEmitterActive (_raveGloveEmitter[i], true);
_raveGloveParticleSystem.setEmitterPosition (_raveGloveEmitter[i], _leapFingerTipBalls[i].position);
_raveGloveParticleSystem.setEmitterDirection(_raveGloveEmitter[i], fingerDirection);
} }
} }
} }

View file

@ -238,8 +238,12 @@ void Head::simulate(float deltaTime, bool isMine, float gyroCameraSensitivity) {
const float CAMERA_STOP_TOLERANCE_DEGREES = 0.5f; const float CAMERA_STOP_TOLERANCE_DEGREES = 0.5f;
const float PITCH_START_RANGE = 20.f; const float PITCH_START_RANGE = 20.f;
const float YAW_START_RANGE = 10.f; const float YAW_START_RANGE = 10.f;
float pitchStartTolerance = PITCH_START_RANGE * (1.f - gyroCameraSensitivity); float pitchStartTolerance = PITCH_START_RANGE
float yawStartTolerance = YAW_START_RANGE * (1.f - gyroCameraSensitivity); * (1.f - gyroCameraSensitivity)
+ (2.f * CAMERA_STOP_TOLERANCE_DEGREES);
float yawStartTolerance = YAW_START_RANGE
* (1.f - gyroCameraSensitivity)
+ (2.f * CAMERA_STOP_TOLERANCE_DEGREES);
float cameraHeadAngleDifference = glm::length(glm::vec2(_pitch - _cameraPitch, _yaw - _cameraYaw)); float cameraHeadAngleDifference = glm::length(glm::vec2(_pitch - _cameraPitch, _yaw - _cameraYaw));
if (_isCameraMoving) { if (_isCameraMoving) {

View file

@ -163,3 +163,77 @@ void GeometryCache::renderSquare(int xDivisions, int yDivisions) {
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
} }
void GeometryCache::renderHalfCylinder(int slices, int stacks) {
VerticesIndices& vbo = _halfCylinderVBOs[IntPair(slices, stacks)];
int vertices = (slices + 1) * stacks;
int indices = 2 * 3 * slices * (stacks - 1);
if (vbo.first == 0) {
GLfloat* vertexData = new GLfloat[vertices * 2 * 3];
GLfloat* vertex = vertexData;
for (int i = 0; i <= (stacks - 1); i++) {
float y = (float)i / (stacks - 1);
for (int j = 0; j <= slices; j++) {
float theta = 3 * PIf / 2 + PIf * j / slices;
//normals
*(vertex++) = sinf(theta);
*(vertex++) = 0;
*(vertex++) = cosf(theta);
// vertices
*(vertex++) = sinf(theta);
*(vertex++) = y;
*(vertex++) = cosf(theta);
}
}
glGenBuffers(1, &vbo.first);
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
const int BYTES_PER_VERTEX = 3 * sizeof(GLfloat);
glBufferData(GL_ARRAY_BUFFER, 2 * vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
delete[] vertexData;
GLushort* indexData = new GLushort[indices];
GLushort* index = indexData;
for (int i = 0; i < stacks - 1; i++) {
GLushort bottom = i * (slices + 1);
GLushort top = bottom + slices + 1;
for (int j = 0; j < slices; j++) {
int next = j + 1;
*(index++) = bottom + j;
*(index++) = top + next;
*(index++) = top + j;
*(index++) = bottom + j;
*(index++) = bottom + next;
*(index++) = top + next;
}
}
glGenBuffers(1, &vbo.second);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
const int BYTES_PER_INDEX = sizeof(GLushort);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
delete[] indexData;
} else {
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 6 * sizeof(float), 0);
glVertexPointer(3, GL_FLOAT, (6 * sizeof(float)), (const void *)(3 * sizeof(float)));
glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

View file

@ -20,6 +20,7 @@ public:
void renderHemisphere(int slices, int stacks); void renderHemisphere(int slices, int stacks);
void renderSquare(int xDivisions, int yDivisions); void renderSquare(int xDivisions, int yDivisions);
void renderHalfCylinder(int slices, int stacks);
private: private:
@ -28,6 +29,7 @@ private:
QHash<IntPair, VerticesIndices> _hemisphereVBOs; QHash<IntPair, VerticesIndices> _hemisphereVBOs;
QHash<IntPair, VerticesIndices> _squareVBOs; QHash<IntPair, VerticesIndices> _squareVBOs;
QHash<IntPair, VerticesIndices> _halfCylinderVBOs;
}; };
#endif /* defined(__interface__GeometryCache__) */ #endif /* defined(__interface__GeometryCache__) */

View file

@ -55,7 +55,7 @@ _numFramesWithoutData(0),
_owningPalmData(owningPalmData), _owningPalmData(owningPalmData),
_owningHandData(owningHandData) _owningHandData(owningHandData)
{ {
const int standardTrailLength = 30; const int standardTrailLength = 10;
setTrailLength(standardTrailLength); setTrailLength(standardTrailLength);
} }
@ -222,9 +222,8 @@ void FingerData::updateTrail() {
_tipTrailCurrentValidLength++; _tipTrailCurrentValidLength++;
} }
else { else {
// It's not active, so just shorten the trail. // It's not active, so just kill the trail.
if (_tipTrailCurrentValidLength > 0) _tipTrailCurrentValidLength = 0;
_tipTrailCurrentValidLength--;
} }
} }

View file

@ -38,7 +38,7 @@ bool pingUnknownNodeThreadStopFlag = false;
NodeList* NodeList::_sharedInstance = NULL; NodeList* NodeList::_sharedInstance = NULL;
NodeList* NodeList::createInstance(char ownerType, unsigned int socketListenPort) { NodeList* NodeList::createInstance(char ownerType, unsigned short int socketListenPort) {
if (!_sharedInstance) { if (!_sharedInstance) {
_sharedInstance = new NodeList(ownerType, socketListenPort); _sharedInstance = new NodeList(ownerType, socketListenPort);
} else { } else {
@ -56,7 +56,7 @@ NodeList* NodeList::getInstance() {
return _sharedInstance; return _sharedInstance;
} }
NodeList::NodeList(char newOwnerType, unsigned int newSocketListenPort) : NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) :
_nodeBuckets(), _nodeBuckets(),
_numNodes(0), _numNodes(0),
_nodeSocket(newSocketListenPort), _nodeSocket(newSocketListenPort),

View file

@ -28,7 +28,7 @@ const int MAX_NUM_NODES = 10000;
const int NODES_PER_BUCKET = 100; const int NODES_PER_BUCKET = 100;
const int MAX_PACKET_SIZE = 1500; const int MAX_PACKET_SIZE = 1500;
const unsigned int NODE_SOCKET_LISTEN_PORT = 40103; const unsigned short int NODE_SOCKET_LISTEN_PORT = 40103;
const int NODE_SILENCE_THRESHOLD_USECS = 2 * 1000000; const int NODE_SILENCE_THRESHOLD_USECS = 2 * 1000000;
const int DOMAIN_SERVER_CHECK_IN_USECS = 1 * 1000000; const int DOMAIN_SERVER_CHECK_IN_USECS = 1 * 1000000;
@ -55,7 +55,7 @@ public:
class NodeList { class NodeList {
public: public:
static NodeList* createInstance(char ownerType, unsigned int socketListenPort = NODE_SOCKET_LISTEN_PORT); static NodeList* createInstance(char ownerType, unsigned short int socketListenPort = NODE_SOCKET_LISTEN_PORT);
static NodeList* getInstance(); static NodeList* getInstance();
typedef NodeListIterator iterator; typedef NodeListIterator iterator;
@ -81,7 +81,7 @@ public:
UDPSocket* getNodeSocket() { return &_nodeSocket; } UDPSocket* getNodeSocket() { return &_nodeSocket; }
unsigned int getSocketListenPort() const { return _nodeSocket.getListeningPort(); }; unsigned short int getSocketListenPort() const { return _nodeSocket.getListeningPort(); };
void(*linkedDataCreateCallback)(Node *); void(*linkedDataCreateCallback)(Node *);
@ -128,7 +128,7 @@ public:
private: private:
static NodeList* _sharedInstance; static NodeList* _sharedInstance;
NodeList(char ownerType, unsigned int socketListenPort); NodeList(char ownerType, unsigned short int socketListenPort);
~NodeList(); ~NodeList();
NodeList(NodeList const&); // Don't implement, needed to avoid copies of singleton NodeList(NodeList const&); // Don't implement, needed to avoid copies of singleton
void operator=(NodeList const&); // Don't implement, needed to avoid copies of singleton void operator=(NodeList const&); // Don't implement, needed to avoid copies of singleton
@ -142,7 +142,6 @@ private:
UDPSocket _nodeSocket; UDPSocket _nodeSocket;
char _ownerType; char _ownerType;
char* _nodeTypesOfInterest; char* _nodeTypesOfInterest;
unsigned int _socketListenPort;
uint16_t _ownerID; uint16_t _ownerID;
uint16_t _lastNodeID; uint16_t _lastNodeID;
pthread_t removeSilentNodesThread; pthread_t removeSilentNodesThread;

View file

@ -129,7 +129,10 @@ sockaddr_in socketForHostname(const char* hostname) {
return newSocket; return newSocket;
} }
UDPSocket::UDPSocket(int listeningPort) : listeningPort(listeningPort), blocking(true) { UDPSocket::UDPSocket(unsigned short int listeningPort) :
_listeningPort(listeningPort),
blocking(true)
{
init(); init();
// create the socket // create the socket
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
@ -145,10 +148,10 @@ UDPSocket::UDPSocket(int listeningPort) : listeningPort(listeningPort), blocking
sockaddr_in bind_address; sockaddr_in bind_address;
bind_address.sin_family = AF_INET; bind_address.sin_family = AF_INET;
bind_address.sin_addr.s_addr = INADDR_ANY; bind_address.sin_addr.s_addr = INADDR_ANY;
bind_address.sin_port = htons((uint16_t) listeningPort); bind_address.sin_port = htons((uint16_t) _listeningPort);
if (bind(handle, (const sockaddr*) &bind_address, sizeof(sockaddr_in)) < 0) { if (bind(handle, (const sockaddr*) &bind_address, sizeof(sockaddr_in)) < 0) {
qDebug("Failed to bind socket to port %d.\n", listeningPort); qDebug("Failed to bind socket to port %hu.\n", _listeningPort);
return; return;
} }
@ -156,7 +159,7 @@ UDPSocket::UDPSocket(int listeningPort) : listeningPort(listeningPort), blocking
if (listeningPort == 0) { if (listeningPort == 0) {
socklen_t addressLength = sizeof(sockaddr_in); socklen_t addressLength = sizeof(sockaddr_in);
getsockname(handle, (sockaddr*) &bind_address, &addressLength); getsockname(handle, (sockaddr*) &bind_address, &addressLength);
listeningPort = ntohs(bind_address.sin_port); _listeningPort = ntohs(bind_address.sin_port);
} }
// set timeout on socket recieve to 0.5 seconds // set timeout on socket recieve to 0.5 seconds
@ -165,7 +168,7 @@ UDPSocket::UDPSocket(int listeningPort) : listeningPort(listeningPort), blocking
tv.tv_usec = 500000; tv.tv_usec = 500000;
setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv); setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv);
qDebug("Created UDP socket listening on port %d.\n", listeningPort); qDebug("Created UDP socket listening on port %hu.\n", _listeningPort);
} }
UDPSocket::~UDPSocket() { UDPSocket::~UDPSocket() {

View file

@ -20,10 +20,10 @@
class UDPSocket { class UDPSocket {
public: public:
UDPSocket(int listening_port); UDPSocket(unsigned short int listeningPort);
~UDPSocket(); ~UDPSocket();
bool init(); bool init();
int getListeningPort() const { return listeningPort; } unsigned short int getListeningPort() const { return _listeningPort; }
void setBlocking(bool blocking); void setBlocking(bool blocking);
bool isBlocking() const { return blocking; } bool isBlocking() const { return blocking; }
int send(sockaddr* destAddress, const void* data, size_t byteLength) const; int send(sockaddr* destAddress, const void* data, size_t byteLength) const;
@ -32,7 +32,7 @@ public:
bool receive(sockaddr* recvAddress, void* receivedData, ssize_t* receivedBytes) const; bool receive(sockaddr* recvAddress, void* receivedData, ssize_t* receivedBytes) const;
private: private:
int handle; int handle;
int listeningPort; unsigned short int _listeningPort;
bool blocking; bool blocking;
}; };