mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 18:26:26 +02:00
Merge branch 'master' of https://github.com/worklist/hifi
Conflicts: interface/src/Application.cpp
This commit is contained in:
commit
63aeb4df75
26 changed files with 680 additions and 146 deletions
|
@ -234,6 +234,10 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
|
|
||||||
NodeList::createInstance(NODE_TYPE_AGENT, listenPort);
|
NodeList::createInstance(NODE_TYPE_AGENT, listenPort);
|
||||||
|
|
||||||
|
NodeList::getInstance()->addHook(&_voxels);
|
||||||
|
NodeList::getInstance()->addHook(this);
|
||||||
|
|
||||||
|
|
||||||
_enableNetworkThread = !cmdOptionExists(argc, constArgv, "--nonblocking");
|
_enableNetworkThread = !cmdOptionExists(argc, constArgv, "--nonblocking");
|
||||||
if (!_enableNetworkThread) {
|
if (!_enableNetworkThread) {
|
||||||
NodeList::getInstance()->getNodeSocket()->setBlocking(false);
|
NodeList::getInstance()->getNodeSocket()->setBlocking(false);
|
||||||
|
@ -317,6 +321,11 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
// initialization continues in initializeGL when OpenGL context is ready
|
// initialization continues in initializeGL when OpenGL context is ready
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Application::~Application() {
|
||||||
|
NodeList::getInstance()->removeHook(&_voxels);
|
||||||
|
NodeList::getInstance()->removeHook(this);
|
||||||
|
}
|
||||||
|
|
||||||
void Application::initializeGL() {
|
void Application::initializeGL() {
|
||||||
qDebug( "Created Display Window.\n" );
|
qDebug( "Created Display Window.\n" );
|
||||||
|
|
||||||
|
@ -1290,9 +1299,9 @@ void Application::editPreferences() {
|
||||||
horizontalFieldOfView->setValue(_horizontalFieldOfView);
|
horizontalFieldOfView->setValue(_horizontalFieldOfView);
|
||||||
form->addRow("Horizontal field of view (degrees):", horizontalFieldOfView);
|
form->addRow("Horizontal field of view (degrees):", horizontalFieldOfView);
|
||||||
|
|
||||||
QDoubleSpinBox* headCameraPitchYawScale = new QDoubleSpinBox();
|
QDoubleSpinBox* gyroCameraSensitivity = new QDoubleSpinBox();
|
||||||
headCameraPitchYawScale->setValue(_headCameraPitchYawScale);
|
gyroCameraSensitivity->setValue(_gyroCameraSensitivity);
|
||||||
form->addRow("Head Camera Pitch/Yaw Scale:", headCameraPitchYawScale);
|
form->addRow("Gyro Camera Sensitivity (0 - 1):", gyroCameraSensitivity);
|
||||||
|
|
||||||
QDoubleSpinBox* leanScale = new QDoubleSpinBox();
|
QDoubleSpinBox* leanScale = new QDoubleSpinBox();
|
||||||
leanScale->setValue(_myAvatar.getLeanScale());
|
leanScale->setValue(_myAvatar.getLeanScale());
|
||||||
|
@ -1342,7 +1351,7 @@ void Application::editPreferences() {
|
||||||
_myAvatar.getVoxels()->setVoxelURL(url);
|
_myAvatar.getVoxels()->setVoxelURL(url);
|
||||||
sendAvatarVoxelURLMessage(url);
|
sendAvatarVoxelURLMessage(url);
|
||||||
|
|
||||||
_headCameraPitchYawScale = headCameraPitchYawScale->value();
|
_gyroCameraSensitivity = gyroCameraSensitivity->value();
|
||||||
_myAvatar.setLeanScale(leanScale->value());
|
_myAvatar.setLeanScale(leanScale->value());
|
||||||
_audioJitterBufferSamples = audioJitterBufferSamples->value();
|
_audioJitterBufferSamples = audioJitterBufferSamples->value();
|
||||||
if (!shouldDynamicallySetJitterBuffer()) {
|
if (!shouldDynamicallySetJitterBuffer()) {
|
||||||
|
@ -1944,6 +1953,7 @@ void Application::initMenu() {
|
||||||
(_fullScreenMode = optionsMenu->addAction("Fullscreen", this, SLOT(setFullscreen(bool)), Qt::Key_F))->setCheckable(true);
|
(_fullScreenMode = optionsMenu->addAction("Fullscreen", this, SLOT(setFullscreen(bool)), Qt::Key_F))->setCheckable(true);
|
||||||
optionsMenu->addAction("Webcam", &_webcam, SLOT(setEnabled(bool)))->setCheckable(true);
|
optionsMenu->addAction("Webcam", &_webcam, SLOT(setEnabled(bool)))->setCheckable(true);
|
||||||
optionsMenu->addAction("Skeleton Tracking", &_webcam, SLOT(setSkeletonTrackingOn(bool)))->setCheckable(true);
|
optionsMenu->addAction("Skeleton Tracking", &_webcam, SLOT(setSkeletonTrackingOn(bool)))->setCheckable(true);
|
||||||
|
(_wantCollisionsOn = optionsMenu->addAction("Turn collisions On", this, SLOT(toggleWantCollisionsOn())))->setCheckable(true);
|
||||||
optionsMenu->addAction("Cycle Webcam Send Mode", _webcam.getGrabber(), SLOT(cycleVideoSendMode()));
|
optionsMenu->addAction("Cycle Webcam Send Mode", _webcam.getGrabber(), SLOT(cycleVideoSendMode()));
|
||||||
optionsMenu->addAction("Webcam Texture", _webcam.getGrabber(), SLOT(setDepthOnly(bool)))->setCheckable(true);
|
optionsMenu->addAction("Webcam Texture", _webcam.getGrabber(), SLOT(setDepthOnly(bool)))->setCheckable(true);
|
||||||
optionsMenu->addAction("Go Home", this, SLOT(goHome()), Qt::CTRL | Qt::Key_G);
|
optionsMenu->addAction("Go Home", this, SLOT(goHome()), Qt::CTRL | Qt::Key_G);
|
||||||
|
@ -2138,6 +2148,10 @@ void Application::toggleMixedSong() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::toggleWantCollisionsOn() {
|
||||||
|
_myAvatar.setWantCollisionsOn(_wantCollisionsOn->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
void Application::resetSongMixMenuItem() {
|
void Application::resetSongMixMenuItem() {
|
||||||
if (_audio.getSongFileBytes() == 0) {
|
if (_audio.getSongFileBytes() == 0) {
|
||||||
_rawAudioMicrophoneMix->setText("Mix RAW Song");
|
_rawAudioMicrophoneMix->setText("Mix RAW Song");
|
||||||
|
@ -2288,6 +2302,56 @@ void Application::renderLookatIndicator(glm::vec3 pointOfInterest, Camera& which
|
||||||
renderCircle(haloOrigin, INDICATOR_RADIUS, IDENTITY_UP, NUM_SEGMENTS);
|
renderCircle(haloOrigin, INDICATOR_RADIUS, IDENTITY_UP, NUM_SEGMENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::renderFollowIndicator() {
|
||||||
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
|
glLineWidth(5);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); ++node) {
|
||||||
|
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||||
|
Avatar* avatar = (Avatar *) node->getLinkedData();
|
||||||
|
Avatar* leader = NULL;
|
||||||
|
|
||||||
|
if (avatar->getLeaderID() != UNKNOWN_NODE_ID) {
|
||||||
|
if (avatar->getLeaderID() == NodeList::getInstance()->getOwnerID()) {
|
||||||
|
leader = &_myAvatar;
|
||||||
|
} else {
|
||||||
|
for (NodeList::iterator it = nodeList->begin(); it != nodeList->end(); ++it) {
|
||||||
|
if(it->getNodeID() == avatar->getLeaderID()
|
||||||
|
&& it->getType() == NODE_TYPE_AGENT) {
|
||||||
|
leader = (Avatar*) it->getLinkedData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leader != NULL) {
|
||||||
|
glColor3f(1.f, 0.f, 0.f);
|
||||||
|
glVertex3f(avatar->getPosition().x,
|
||||||
|
avatar->getPosition().y,
|
||||||
|
avatar->getPosition().z);
|
||||||
|
glColor3f(0.f, 1.f, 0.f);
|
||||||
|
glVertex3f(leader->getPosition().x,
|
||||||
|
leader->getPosition().y,
|
||||||
|
leader->getPosition().z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_myAvatar.getLeadingAvatar() != NULL) {
|
||||||
|
glColor3f(1.f, 0.f, 0.f);
|
||||||
|
glVertex3f(_myAvatar.getPosition().x,
|
||||||
|
_myAvatar.getPosition().y,
|
||||||
|
_myAvatar.getPosition().z);
|
||||||
|
glColor3f(0.f, 1.f, 0.f);
|
||||||
|
glVertex3f(_myAvatar.getLeadingAvatar()->getPosition().x,
|
||||||
|
_myAvatar.getLeadingAvatar()->getPosition().y,
|
||||||
|
_myAvatar.getLeadingAvatar()->getPosition().z);
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
void Application::update(float deltaTime) {
|
void Application::update(float deltaTime) {
|
||||||
|
|
||||||
// Use Transmitter Hand to move hand if connected, else use mouse
|
// Use Transmitter Hand to move hand if connected, else use mouse
|
||||||
|
@ -2501,7 +2565,7 @@ void Application::update(float deltaTime) {
|
||||||
if (!avatar->isInitialized()) {
|
if (!avatar->isInitialized()) {
|
||||||
avatar->init();
|
avatar->init();
|
||||||
}
|
}
|
||||||
avatar->simulate(deltaTime, NULL);
|
avatar->simulate(deltaTime, NULL, 0.f);
|
||||||
avatar->setMouseRay(mouseRayOrigin, mouseRayDirection);
|
avatar->setMouseRay(mouseRayOrigin, mouseRayDirection);
|
||||||
}
|
}
|
||||||
node->unlock();
|
node->unlock();
|
||||||
|
@ -2516,9 +2580,9 @@ void Application::update(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_transmitterDrives->isChecked() && _myTransmitter.isConnected()) {
|
if (_transmitterDrives->isChecked() && _myTransmitter.isConnected()) {
|
||||||
_myAvatar.simulate(deltaTime, &_myTransmitter);
|
_myAvatar.simulate(deltaTime, &_myTransmitter, _gyroCameraSensitivity);
|
||||||
} else {
|
} else {
|
||||||
_myAvatar.simulate(deltaTime, NULL);
|
_myAvatar.simulate(deltaTime, NULL, _gyroCameraSensitivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!OculusManager::isConnected()) {
|
if (!OculusManager::isConnected()) {
|
||||||
|
@ -2585,10 +2649,6 @@ void Application::updateAvatar(float deltaTime) {
|
||||||
|
|
||||||
// Update my avatar's state from gyros and/or webcam
|
// Update my avatar's state from gyros and/or webcam
|
||||||
_myAvatar.updateFromGyrosAndOrWebcam(_gyroLook->isChecked(),
|
_myAvatar.updateFromGyrosAndOrWebcam(_gyroLook->isChecked(),
|
||||||
glm::vec3(_headCameraPitchYawScale,
|
|
||||||
_headCameraPitchYawScale,
|
|
||||||
_headCameraPitchYawScale),
|
|
||||||
0.f,
|
|
||||||
_pitchFromTouch);
|
_pitchFromTouch);
|
||||||
|
|
||||||
if (_serialHeadSensor.isActive()) {
|
if (_serialHeadSensor.isActive()) {
|
||||||
|
@ -3014,6 +3074,8 @@ void Application::displaySide(Camera& whichCamera) {
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_myAvatar.renderScreenTint(SCREEN_TINT_BEFORE_AVATARS);
|
||||||
|
|
||||||
if (_renderAvatarsOn->isChecked()) {
|
if (_renderAvatarsOn->isChecked()) {
|
||||||
// Render avatars of other nodes
|
// Render avatars of other nodes
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
@ -3059,6 +3121,20 @@ void Application::displaySide(Camera& whichCamera) {
|
||||||
|
|
||||||
// brad's frustum for debugging
|
// brad's frustum for debugging
|
||||||
if (_frustumOn->isChecked()) renderViewFrustum(_viewFrustum);
|
if (_frustumOn->isChecked()) renderViewFrustum(_viewFrustum);
|
||||||
|
|
||||||
|
// render voxel fades if they exist
|
||||||
|
if (_voxelFades.size() > 0) {
|
||||||
|
for(std::vector<VoxelFade>::iterator fade = _voxelFades.begin(); fade != _voxelFades.end();) {
|
||||||
|
fade->render();
|
||||||
|
if(fade->isDone()) {
|
||||||
|
fade = _voxelFades.erase(fade);
|
||||||
|
} else {
|
||||||
|
++fade;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderFollowIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::displayOverlay() {
|
void Application::displayOverlay() {
|
||||||
|
@ -3626,6 +3702,62 @@ void Application::shiftPaintingColor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Application::injectVoxelAddedSoundEffect() {
|
||||||
|
AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(11025);
|
||||||
|
|
||||||
|
if (voxelInjector) {
|
||||||
|
voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z));
|
||||||
|
//voxelInjector->setBearing(-1 * _myAvatar.getAbsoluteHeadYaw());
|
||||||
|
voxelInjector->setVolume (16 * pow (_mouseVoxel.s, 2) / .0000001); //255 is max, and also default value
|
||||||
|
|
||||||
|
/* for (int i = 0; i
|
||||||
|
< 22050; i++) {
|
||||||
|
if (i % 4 == 0) {
|
||||||
|
voxelInjector->addSample(4000);
|
||||||
|
} else if (i % 4 == 1) {
|
||||||
|
voxelInjector->addSample(0);
|
||||||
|
} else if (i % 4 == 2) {
|
||||||
|
voxelInjector->addSample(-4000);
|
||||||
|
} else {
|
||||||
|
voxelInjector->addSample(0);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const float BIG_VOXEL_MIN_SIZE = .01f;
|
||||||
|
|
||||||
|
for (int i = 0; i < 11025; i++) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
A440 square wave
|
||||||
|
if (sin(i * 2 * PIE / 50)>=0) {
|
||||||
|
voxelInjector->addSample(4000);
|
||||||
|
} else {
|
||||||
|
voxelInjector->addSample(-4000);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (_mouseVoxel.s > BIG_VOXEL_MIN_SIZE) {
|
||||||
|
voxelInjector->addSample(20000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 200))));
|
||||||
|
} else {
|
||||||
|
voxelInjector->addSample(16000 * sin(i / (1.5 * log (_mouseVoxel.s / .0001) * ((i + 11025) / 5512.5)))); //808
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//voxelInjector->addSample(32500 * sin(i/(2 * 1 * ((i+5000)/5512.5)))); //80
|
||||||
|
//voxelInjector->addSample(20000 * sin(i/(6 * (_mouseVoxel.s/.001) *((i+5512.5)/5512.5)))); //808
|
||||||
|
//voxelInjector->addSample(20000 * sin(i/(6 * ((i+5512.5)/5512.5)))); //808
|
||||||
|
//voxelInjector->addSample(4000 * sin(i * 2 * PIE /50)); //A440 sine wave
|
||||||
|
//voxelInjector->addSample(4000 * sin(i * 2 * PIE /50) * sin (i/500)); //A440 sine wave with amplitude modulation
|
||||||
|
|
||||||
|
//FM library
|
||||||
|
//voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(500*sin((i+1)/200)))); //FM 1 dubstep
|
||||||
|
//voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(300*sin((i+1)/5.0)))); //FM 2 flange sweep
|
||||||
|
//voxelInjector->addSample(10000 * sin((i * 2 * PIE) /(500*sin((i+1)/500.0)))); //FM 3 resonant pulse
|
||||||
|
|
||||||
|
AudioInjectionManager::threadInjector(voxelInjector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Application::maybeEditVoxelUnderCursor() {
|
bool Application::maybeEditVoxelUnderCursor() {
|
||||||
if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) {
|
if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) {
|
||||||
if (_mouseVoxel.s != 0) {
|
if (_mouseVoxel.s != 0) {
|
||||||
|
@ -3636,65 +3768,35 @@ bool Application::maybeEditVoxelUnderCursor() {
|
||||||
// create the voxel locally so it appears immediately
|
// create the voxel locally so it appears immediately
|
||||||
_voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s,
|
_voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s,
|
||||||
_mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel->isChecked());
|
_mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel->isChecked());
|
||||||
|
|
||||||
|
// Implement voxel fade effect
|
||||||
|
VoxelFade fade(VoxelFade::FADE_OUT, 1.0f, 1.0f, 1.0f);
|
||||||
|
const float VOXEL_BOUNDS_ADJUST = 0.01f;
|
||||||
|
float slightlyBigger = _mouseVoxel.s * VOXEL_BOUNDS_ADJUST;
|
||||||
|
fade.voxelDetails.x = _mouseVoxel.x - slightlyBigger;
|
||||||
|
fade.voxelDetails.y = _mouseVoxel.y - slightlyBigger;
|
||||||
|
fade.voxelDetails.z = _mouseVoxel.z - slightlyBigger;
|
||||||
|
fade.voxelDetails.s = _mouseVoxel.s + slightlyBigger + slightlyBigger;
|
||||||
|
_voxelFades.push_back(fade);
|
||||||
|
|
||||||
|
// inject a sound effect
|
||||||
|
injectVoxelAddedSoundEffect();
|
||||||
|
|
||||||
// remember the position for drag detection
|
// remember the position for drag detection
|
||||||
_justEditedVoxel = true;
|
_justEditedVoxel = true;
|
||||||
|
|
||||||
AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(11025);
|
|
||||||
voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z));
|
|
||||||
//_myAvatar.getPosition()
|
|
||||||
// voxelInjector->setBearing(-1 * _myAvatar.getAbsoluteHeadYaw());
|
|
||||||
voxelInjector->setVolume (16 * pow (_mouseVoxel.s, 2) / .0000001); //255 is max, and also default value
|
|
||||||
|
|
||||||
/* for (int i = 0; i
|
|
||||||
< 22050; i++) {
|
|
||||||
if (i % 4 == 0) {
|
|
||||||
voxelInjector->addSample(4000);
|
|
||||||
} else if (i % 4 == 1) {
|
|
||||||
voxelInjector->addSample(0);
|
|
||||||
} else if (i % 4 == 2) {
|
|
||||||
voxelInjector->addSample(-4000);
|
|
||||||
} else {
|
|
||||||
voxelInjector->addSample(0);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
const float BIG_VOXEL_MIN_SIZE = .01f;
|
|
||||||
|
|
||||||
for (int i = 0; i < 11025; i++) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
A440 square wave
|
|
||||||
if (sin(i * 2 * PIE / 50)>=0) {
|
|
||||||
voxelInjector->addSample(4000);
|
|
||||||
} else {
|
|
||||||
voxelInjector->addSample(-4000);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (_mouseVoxel.s > BIG_VOXEL_MIN_SIZE) {
|
|
||||||
voxelInjector->addSample(20000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 200))));
|
|
||||||
} else {
|
|
||||||
voxelInjector->addSample(16000 * sin(i / (1.5 * log (_mouseVoxel.s / .0001) * ((i + 11025) / 5512.5)))); //808
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//voxelInjector->addSample(32500 * sin(i/(2 * 1 * ((i+5000)/5512.5)))); //80
|
|
||||||
//voxelInjector->addSample(20000 * sin(i/(6 * (_mouseVoxel.s/.001) *((i+5512.5)/5512.5)))); //808
|
|
||||||
//voxelInjector->addSample(20000 * sin(i/(6 * ((i+5512.5)/5512.5)))); //808
|
|
||||||
//voxelInjector->addSample(4000 * sin(i * 2 * PIE /50)); //A440 sine wave
|
|
||||||
//voxelInjector->addSample(4000 * sin(i * 2 * PIE /50) * sin (i/500)); //A440 sine wave with amplitude modulation
|
|
||||||
|
|
||||||
//FM library
|
|
||||||
//voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(500*sin((i+1)/200)))); //FM 1 dubstep
|
|
||||||
//voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(300*sin((i+1)/5.0)))); //FM 2 flange sweep
|
|
||||||
//voxelInjector->addSample(10000 * sin((i * 2 * PIE) /(500*sin((i+1)/500.0)))); //FM 3 resonant pulse
|
|
||||||
|
|
||||||
AudioInjectionManager::threadInjector(voxelInjector);
|
|
||||||
}
|
}
|
||||||
} else if (_deleteVoxelMode->isChecked()) {
|
} else if (_deleteVoxelMode->isChecked()) {
|
||||||
deleteVoxelUnderCursor();
|
deleteVoxelUnderCursor();
|
||||||
|
VoxelFade fade(VoxelFade::FADE_OUT, NODE_KILLED_RED, NODE_KILLED_GREEN, NODE_KILLED_BLUE);
|
||||||
|
const float VOXEL_BOUNDS_ADJUST = 0.01f;
|
||||||
|
float slightlyBigger = _mouseVoxel.s * VOXEL_BOUNDS_ADJUST;
|
||||||
|
fade.voxelDetails.x = _mouseVoxel.x - slightlyBigger;
|
||||||
|
fade.voxelDetails.y = _mouseVoxel.y - slightlyBigger;
|
||||||
|
fade.voxelDetails.z = _mouseVoxel.z - slightlyBigger;
|
||||||
|
fade.voxelDetails.s = _mouseVoxel.s + slightlyBigger + slightlyBigger;
|
||||||
|
_voxelFades.push_back(fade);
|
||||||
|
|
||||||
} else if (_eyedropperMode->isChecked()) {
|
} else if (_eyedropperMode->isChecked()) {
|
||||||
eyedropperVoxelUnderCursor();
|
eyedropperVoxelUnderCursor();
|
||||||
} else {
|
} else {
|
||||||
|
@ -3709,17 +3811,20 @@ void Application::deleteVoxelUnderCursor() {
|
||||||
// sending delete to the server is sufficient, server will send new version so we see updates soon enough
|
// sending delete to the server is sufficient, server will send new version so we see updates soon enough
|
||||||
sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, _mouseVoxel);
|
sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, _mouseVoxel);
|
||||||
AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(5000);
|
AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(5000);
|
||||||
voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z));
|
|
||||||
// voxelInjector->setBearing(0); //straight down the z axis
|
|
||||||
voxelInjector->setVolume (255); //255 is max, and also default value
|
|
||||||
|
|
||||||
|
if (voxelInjector) {
|
||||||
for (int i = 0; i < 5000; i++) {
|
voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z));
|
||||||
voxelInjector->addSample(10000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 500.0)))); //FM 3 resonant pulse
|
//voxelInjector->setBearing(0); //straight down the z axis
|
||||||
//voxelInjector->addSample(20000 * sin((i) /((4 / _mouseVoxel.s) * sin((i)/(20 * _mouseVoxel.s / .001))))); //FM 2 comb filter
|
voxelInjector->setVolume (255); //255 is max, and also default value
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < 5000; i++) {
|
||||||
|
voxelInjector->addSample(10000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 500.0)))); //FM 3 resonant pulse
|
||||||
|
//voxelInjector->addSample(20000 * sin((i) /((4 / _mouseVoxel.s) * sin((i)/(20 * _mouseVoxel.s / .001))))); //FM 2 comb filter
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioInjectionManager::threadInjector(voxelInjector);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioInjectionManager::threadInjector(voxelInjector);
|
|
||||||
}
|
}
|
||||||
// remember the position for drag detection
|
// remember the position for drag detection
|
||||||
_justEditedVoxel = true;
|
_justEditedVoxel = true;
|
||||||
|
@ -3816,6 +3921,57 @@ void Application::attachNewHeadToNode(Node* newNode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::nodeAdded(Node* node) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::nodeKilled(Node* node) {
|
||||||
|
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||||
|
uint16_t nodeID = node->getNodeID();
|
||||||
|
// see if this is the first we've heard of this node...
|
||||||
|
if (_voxelServerJurisdictions.find(nodeID) != _voxelServerJurisdictions.end()) {
|
||||||
|
VoxelPositionSize jurisditionDetails;
|
||||||
|
jurisditionDetails = _voxelServerJurisdictions[nodeID];
|
||||||
|
|
||||||
|
printf("voxel server going away...... v[%f, %f, %f, %f]\n",
|
||||||
|
jurisditionDetails.x, jurisditionDetails.y, jurisditionDetails.z, jurisditionDetails.s);
|
||||||
|
|
||||||
|
// Add the jurisditionDetails object to the list of "fade outs"
|
||||||
|
VoxelFade fade(VoxelFade::FADE_OUT, NODE_KILLED_RED, NODE_KILLED_GREEN, NODE_KILLED_BLUE);
|
||||||
|
fade.voxelDetails = jurisditionDetails;
|
||||||
|
_voxelFades.push_back(fade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress) {
|
||||||
|
|
||||||
|
// parse the incoming stats data, and stick it into our averaging stats object for now... even though this
|
||||||
|
// means mixing in stats from potentially multiple servers.
|
||||||
|
int statsMessageLength = _voxelSceneStats.unpackFromMessage(messageData, messageLength);
|
||||||
|
|
||||||
|
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
|
||||||
|
Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||||
|
uint16_t nodeID = voxelServer->getNodeID();
|
||||||
|
|
||||||
|
VoxelPositionSize jurisditionDetails;
|
||||||
|
voxelDetailsForCode(_voxelSceneStats.getJurisdictionRoot(), jurisditionDetails);
|
||||||
|
|
||||||
|
// see if this is the first we've heard of this node...
|
||||||
|
if (_voxelServerJurisdictions.find(nodeID) == _voxelServerJurisdictions.end()) {
|
||||||
|
printf("stats from new voxel server... v[%f, %f, %f, %f]\n",
|
||||||
|
jurisditionDetails.x, jurisditionDetails.y, jurisditionDetails.z, jurisditionDetails.s);
|
||||||
|
|
||||||
|
// Add the jurisditionDetails object to the list of "fade outs"
|
||||||
|
VoxelFade fade(VoxelFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE);
|
||||||
|
fade.voxelDetails = jurisditionDetails;
|
||||||
|
_voxelFades.push_back(fade);
|
||||||
|
}
|
||||||
|
// store jurisdiction details for later use
|
||||||
|
_voxelServerJurisdictions[nodeID] = jurisditionDetails;
|
||||||
|
|
||||||
|
return statsMessageLength;
|
||||||
|
}
|
||||||
|
|
||||||
// Receive packets from other nodes/servers and decide what to do with them!
|
// Receive packets from other nodes/servers and decide what to do with them!
|
||||||
void* Application::networkReceive(void* args) {
|
void* Application::networkReceive(void* args) {
|
||||||
sockaddr senderAddress;
|
sockaddr senderAddress;
|
||||||
|
@ -3859,7 +4015,8 @@ void* Application::networkReceive(void* args) {
|
||||||
// immediately following them inside the same packet. So, we process the PACKET_TYPE_VOXEL_STATS first
|
// immediately following them inside the same packet. So, we process the PACKET_TYPE_VOXEL_STATS first
|
||||||
// then process any remaining bytes as if it was another packet
|
// then process any remaining bytes as if it was another packet
|
||||||
if (messageData[0] == PACKET_TYPE_VOXEL_STATS) {
|
if (messageData[0] == PACKET_TYPE_VOXEL_STATS) {
|
||||||
int statsMessageLength = app->_voxelSceneStats.unpackFromMessage(messageData, messageLength);
|
|
||||||
|
int statsMessageLength = app->parseVoxelStats(messageData, messageLength, senderAddress);
|
||||||
if (messageLength > statsMessageLength) {
|
if (messageLength > statsMessageLength) {
|
||||||
messageData += statsMessageLength;
|
messageData += statsMessageLength;
|
||||||
messageLength -= statsMessageLength;
|
messageLength -= statsMessageLength;
|
||||||
|
@ -3953,11 +4110,11 @@ void Application::saveAction(QSettings* set, QAction* action) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::loadSettings(QSettings* settings) {
|
void Application::loadSettings(QSettings* settings) {
|
||||||
if (!settings) {
|
if (!settings) {
|
||||||
settings = getSettings();
|
settings = getSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
_headCameraPitchYawScale = loadSetting(settings, "headCameraPitchYawScale", 0.0f);
|
_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);
|
_horizontalFieldOfView = loadSetting(settings, "horizontalFieldOfView", HORIZONTAL_FIELD_OF_VIEW_DEGREES);
|
||||||
|
|
||||||
|
@ -3981,7 +4138,7 @@ void Application::saveSettings(QSettings* settings) {
|
||||||
settings = getSettings();
|
settings = getSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
settings->setValue("headCameraPitchYawScale", _headCameraPitchYawScale);
|
settings->setValue("gyroCameraSensitivity", _gyroCameraSensitivity);
|
||||||
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
|
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
|
||||||
settings->setValue("horizontalFieldOfView", _horizontalFieldOfView);
|
settings->setValue("horizontalFieldOfView", _horizontalFieldOfView);
|
||||||
settings->beginGroup("View Frustum Offset Camera");
|
settings->beginGroup("View Frustum Offset Camera");
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "Swatch.h"
|
#include "Swatch.h"
|
||||||
#include "ToolsPalette.h"
|
#include "ToolsPalette.h"
|
||||||
#include "ViewFrustum.h"
|
#include "ViewFrustum.h"
|
||||||
|
#include "VoxelFade.h"
|
||||||
#include "VoxelSystem.h"
|
#include "VoxelSystem.h"
|
||||||
#include "Webcam.h"
|
#include "Webcam.h"
|
||||||
#include "PieMenu.h"
|
#include "PieMenu.h"
|
||||||
|
@ -60,13 +61,23 @@ class QWheelEvent;
|
||||||
class Node;
|
class Node;
|
||||||
class ProgramObject;
|
class ProgramObject;
|
||||||
|
|
||||||
class Application : public QApplication {
|
static const float NODE_ADDED_RED = 0.0f;
|
||||||
|
static const float NODE_ADDED_GREEN = 1.0f;
|
||||||
|
static const float NODE_ADDED_BLUE = 0.0f;
|
||||||
|
static const float NODE_KILLED_RED = 1.0f;
|
||||||
|
static const float NODE_KILLED_GREEN = 0.0f;
|
||||||
|
static const float NODE_KILLED_BLUE = 0.0f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Application : public QApplication, public NodeListHook {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Application* getInstance() { return static_cast<Application*>(QCoreApplication::instance()); }
|
static Application* getInstance() { return static_cast<Application*>(QCoreApplication::instance()); }
|
||||||
|
|
||||||
Application(int& argc, char** argv, timeval &startup_time);
|
Application(int& argc, char** argv, timeval &startup_time);
|
||||||
|
~Application();
|
||||||
|
|
||||||
void initializeGL();
|
void initializeGL();
|
||||||
void paintGL();
|
void paintGL();
|
||||||
|
@ -110,6 +121,9 @@ public:
|
||||||
|
|
||||||
void resetSongMixMenuItem();
|
void resetSongMixMenuItem();
|
||||||
|
|
||||||
|
virtual void nodeAdded(Node* node);
|
||||||
|
virtual void nodeKilled(Node* node);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data);
|
void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data);
|
||||||
|
|
||||||
|
@ -181,6 +195,7 @@ private slots:
|
||||||
void setListenModePoint();
|
void setListenModePoint();
|
||||||
void setListenModeSingleSource();
|
void setListenModeSingleSource();
|
||||||
void toggleMixedSong();
|
void toggleMixedSong();
|
||||||
|
void toggleWantCollisionsOn();
|
||||||
|
|
||||||
|
|
||||||
void renderCoverageMap();
|
void renderCoverageMap();
|
||||||
|
@ -218,6 +233,7 @@ private:
|
||||||
bool isLookingAtMyAvatar(Avatar* avatar);
|
bool isLookingAtMyAvatar(Avatar* avatar);
|
||||||
|
|
||||||
void renderLookatIndicator(glm::vec3 pointOfInterest, Camera& whichCamera);
|
void renderLookatIndicator(glm::vec3 pointOfInterest, Camera& whichCamera);
|
||||||
|
void renderFollowIndicator();
|
||||||
void updateAvatar(float deltaTime);
|
void updateAvatar(float deltaTime);
|
||||||
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
|
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
|
||||||
|
|
||||||
|
@ -235,6 +251,7 @@ private:
|
||||||
void deleteVoxelUnderCursor();
|
void deleteVoxelUnderCursor();
|
||||||
void eyedropperVoxelUnderCursor();
|
void eyedropperVoxelUnderCursor();
|
||||||
void resetSensors();
|
void resetSensors();
|
||||||
|
void injectVoxelAddedSoundEffect();
|
||||||
|
|
||||||
void setMenuShortcutsEnabled(bool enabled);
|
void setMenuShortcutsEnabled(bool enabled);
|
||||||
|
|
||||||
|
@ -296,6 +313,7 @@ private:
|
||||||
QAction* _rawAudioMicrophoneMix; // Mixing of a RAW audio file with microphone stream for rave gloves
|
QAction* _rawAudioMicrophoneMix; // Mixing of a RAW audio file with microphone stream for rave gloves
|
||||||
QAction* _noise;
|
QAction* _noise;
|
||||||
QAction* _occlusionCulling;
|
QAction* _occlusionCulling;
|
||||||
|
QAction* _wantCollisionsOn;
|
||||||
|
|
||||||
QAction* _renderCoverageMapV2;
|
QAction* _renderCoverageMapV2;
|
||||||
QAction* _renderCoverageMap;
|
QAction* _renderCoverageMap;
|
||||||
|
@ -360,7 +378,7 @@ private:
|
||||||
Environment _environment;
|
Environment _environment;
|
||||||
|
|
||||||
int _headMouseX, _headMouseY;
|
int _headMouseX, _headMouseY;
|
||||||
float _headCameraPitchYawScale;
|
float _gyroCameraSensitivity;
|
||||||
|
|
||||||
int _audioJitterBufferSamples; // Number of extra samples to wait before starting audio playback
|
int _audioJitterBufferSamples; // Number of extra samples to wait before starting audio playback
|
||||||
|
|
||||||
|
@ -448,6 +466,11 @@ private:
|
||||||
PieMenu _pieMenu;
|
PieMenu _pieMenu;
|
||||||
|
|
||||||
VoxelSceneStats _voxelSceneStats;
|
VoxelSceneStats _voxelSceneStats;
|
||||||
|
int parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress);
|
||||||
|
|
||||||
|
std::map<uint16_t,VoxelPositionSize> _voxelServerJurisdictions;
|
||||||
|
|
||||||
|
std::vector<VoxelFade> _voxelFades;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__interface__Application__) */
|
#endif /* defined(__interface__Application__) */
|
||||||
|
|
58
interface/src/VoxelFade.cpp
Normal file
58
interface/src/VoxelFade.cpp
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
//
|
||||||
|
// VoxelFade.cpp
|
||||||
|
// interface
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 8/6/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "InterfaceConfig.h"
|
||||||
|
|
||||||
|
#include <VoxelConstants.h>
|
||||||
|
|
||||||
|
#include "VoxelFade.h"
|
||||||
|
|
||||||
|
const float VoxelFade::FADE_OUT_START = 0.5f;
|
||||||
|
const float VoxelFade::FADE_OUT_END = 0.0f;
|
||||||
|
const float VoxelFade::FADE_OUT_STEP = -0.005f;
|
||||||
|
const float VoxelFade::FADE_IN_START = 0.0f;
|
||||||
|
const float VoxelFade::FADE_IN_END = 0.5f;
|
||||||
|
const float VoxelFade::FADE_IN_STEP = 0.005f;
|
||||||
|
const float VoxelFade::DEFAULT_RED = 0.5f;
|
||||||
|
const float VoxelFade::DEFAULT_GREEN = 0.5f;
|
||||||
|
const float VoxelFade::DEFAULT_BLUE = 0.5f;
|
||||||
|
|
||||||
|
VoxelFade::VoxelFade(FadeDirection direction, float red, float green, float blue) :
|
||||||
|
direction(direction),
|
||||||
|
red(red),
|
||||||
|
green(green),
|
||||||
|
blue(blue)
|
||||||
|
{
|
||||||
|
opacity = (direction == FADE_OUT) ? FADE_OUT_START : FADE_IN_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelFade::render() {
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
glPushMatrix();
|
||||||
|
glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE);
|
||||||
|
glColor4f(red, green, blue, opacity);
|
||||||
|
glTranslatef(voxelDetails.x + voxelDetails.s * 0.5f,
|
||||||
|
voxelDetails.y + voxelDetails.s * 0.5f,
|
||||||
|
voxelDetails.z + voxelDetails.s * 0.5f);
|
||||||
|
glLineWidth(1.0f);
|
||||||
|
glutSolidCube(voxelDetails.s);
|
||||||
|
glLineWidth(1.0f);
|
||||||
|
glPopMatrix();
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
|
||||||
|
opacity += (direction == FADE_OUT) ? FADE_OUT_STEP : FADE_IN_STEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VoxelFade::isDone() const {
|
||||||
|
if (direction == FADE_OUT) {
|
||||||
|
return opacity <= FADE_OUT_END;
|
||||||
|
} else {
|
||||||
|
return opacity >= FADE_IN_END;
|
||||||
|
}
|
||||||
|
return true; // unexpected case, assume we're done
|
||||||
|
}
|
43
interface/src/VoxelFade.h
Normal file
43
interface/src/VoxelFade.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// VoxelFade.h
|
||||||
|
// interface
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 8/6/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __interface__VoxelFade__
|
||||||
|
#define __interface__VoxelFade__
|
||||||
|
|
||||||
|
#include <OctalCode.h> // for VoxelPositionSize
|
||||||
|
|
||||||
|
class VoxelFade {
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum FadeDirection { FADE_OUT, FADE_IN};
|
||||||
|
static const float FADE_OUT_START;
|
||||||
|
static const float FADE_OUT_END;
|
||||||
|
static const float FADE_OUT_STEP;
|
||||||
|
static const float FADE_IN_START;
|
||||||
|
static const float FADE_IN_END;
|
||||||
|
static const float FADE_IN_STEP;
|
||||||
|
static const float DEFAULT_RED;
|
||||||
|
static const float DEFAULT_GREEN;
|
||||||
|
static const float DEFAULT_BLUE;
|
||||||
|
|
||||||
|
VoxelPositionSize voxelDetails;
|
||||||
|
FadeDirection direction;
|
||||||
|
float opacity;
|
||||||
|
|
||||||
|
float red;
|
||||||
|
float green;
|
||||||
|
float blue;
|
||||||
|
|
||||||
|
VoxelFade(FadeDirection direction = FADE_OUT, float red = DEFAULT_RED,
|
||||||
|
float green = DEFAULT_GREEN, float blue = DEFAULT_BLUE);
|
||||||
|
|
||||||
|
void render();
|
||||||
|
bool isDone() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __interface__VoxelFade__
|
|
@ -1530,10 +1530,38 @@ void VoxelSystem::falseColorizeOccludedV2() {
|
||||||
VoxelProjectedPolygon::intersects_calls
|
VoxelProjectedPolygon::intersects_calls
|
||||||
);
|
);
|
||||||
//myCoverageMapV2.erase();
|
//myCoverageMapV2.erase();
|
||||||
|
|
||||||
|
|
||||||
_tree->setDirtyBit();
|
_tree->setDirtyBit();
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::nodeAdded(Node* node) {
|
||||||
|
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||||
|
uint16_t nodeID = node->getNodeID();
|
||||||
|
printf("VoxelSystem... voxel server %u added...\n", nodeID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VoxelSystem::killSourceVoxelsOperation(VoxelNode* node, void* extraData) {
|
||||||
|
uint16_t killedNodeID = *(uint16_t*)extraData;
|
||||||
|
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||||
|
VoxelNode* childNode = node->getChildAtIndex(i);
|
||||||
|
if (childNode && childNode->getSourceID()== killedNodeID) {
|
||||||
|
node->safeDeepDeleteChildAtIndex(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::nodeKilled(Node* node) {
|
||||||
|
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||||
|
uint16_t nodeID = node->getNodeID();
|
||||||
|
printf("VoxelSystem... voxel server %u removed...\n", nodeID);
|
||||||
|
|
||||||
|
// Kill any voxels from the local tree
|
||||||
|
_tree->recurseTreeWithOperation(killSourceVoxelsOperation, &nodeID);
|
||||||
|
_tree->setDirtyBit();
|
||||||
|
setupNewVoxelsForDrawing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ class ProgramObject;
|
||||||
|
|
||||||
const int NUM_CHILDREN = 8;
|
const int NUM_CHILDREN = 8;
|
||||||
|
|
||||||
class VoxelSystem : public NodeData, public VoxelNodeDeleteHook {
|
class VoxelSystem : public NodeData, public VoxelNodeDeleteHook, public NodeListHook {
|
||||||
public:
|
public:
|
||||||
VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = MAX_VOXELS_PER_SYSTEM);
|
VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = MAX_VOXELS_PER_SYSTEM);
|
||||||
~VoxelSystem();
|
~VoxelSystem();
|
||||||
|
@ -99,6 +99,8 @@ public:
|
||||||
CoverageMap myCoverageMap;
|
CoverageMap myCoverageMap;
|
||||||
|
|
||||||
virtual void nodeDeleted(VoxelNode* node);
|
virtual void nodeDeleted(VoxelNode* node);
|
||||||
|
virtual void nodeAdded(Node* node);
|
||||||
|
virtual void nodeKilled(Node* node);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float _treeScale;
|
float _treeScale;
|
||||||
|
@ -140,6 +142,7 @@ private:
|
||||||
static bool falseColorizeSubTreeOperation(VoxelNode* node, void* extraData);
|
static bool falseColorizeSubTreeOperation(VoxelNode* node, void* extraData);
|
||||||
static bool falseColorizeOccludedV2Operation(VoxelNode* node, void* extraData);
|
static bool falseColorizeOccludedV2Operation(VoxelNode* node, void* extraData);
|
||||||
static bool falseColorizeBySourceOperation(VoxelNode* node, void* extraData);
|
static bool falseColorizeBySourceOperation(VoxelNode* node, void* extraData);
|
||||||
|
static bool killSourceVoxelsOperation(VoxelNode* node, void* extraData);
|
||||||
|
|
||||||
int updateNodeInArraysAsFullVBO(VoxelNode* node);
|
int updateNodeInArraysAsFullVBO(VoxelNode* node);
|
||||||
int updateNodeInArraysAsPartialVBO(VoxelNode* node);
|
int updateNodeInArraysAsPartialVBO(VoxelNode* node);
|
||||||
|
|
|
@ -294,9 +294,8 @@ void Avatar::reset() {
|
||||||
|
|
||||||
// Update avatar head rotation with sensor data
|
// Update avatar head rotation with sensor data
|
||||||
void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook,
|
void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook,
|
||||||
const glm::vec3& amplifyAngle,
|
|
||||||
float yawFromTouch,
|
|
||||||
float pitchFromTouch) {
|
float pitchFromTouch) {
|
||||||
|
_head.setMousePitch(pitchFromTouch);
|
||||||
SerialInterface* gyros = Application::getInstance()->getSerialHeadSensor();
|
SerialInterface* gyros = Application::getInstance()->getSerialHeadSensor();
|
||||||
Webcam* webcam = Application::getInstance()->getWebcam();
|
Webcam* webcam = Application::getInstance()->getWebcam();
|
||||||
glm::vec3 estimatedPosition, estimatedRotation;
|
glm::vec3 estimatedPosition, estimatedRotation;
|
||||||
|
@ -308,7 +307,6 @@ void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook,
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_head.setPitch(pitchFromTouch);
|
_head.setPitch(pitchFromTouch);
|
||||||
_head.setYaw(yawFromTouch);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (webcam->isActive()) {
|
if (webcam->isActive()) {
|
||||||
|
@ -334,9 +332,15 @@ void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook,
|
||||||
} else {
|
} else {
|
||||||
_head.getFace().clearFrame();
|
_head.getFace().clearFrame();
|
||||||
}
|
}
|
||||||
_head.setPitch(estimatedRotation.x * amplifyAngle.x + pitchFromTouch);
|
|
||||||
_head.setYaw(estimatedRotation.y * amplifyAngle.y + yawFromTouch);
|
// Set the rotation of the avatar's head (as seen by others, not affecting view frustum)
|
||||||
_head.setRoll(estimatedRotation.z * amplifyAngle.z);
|
// to be scaled. Pitch is greater to emphasize nodding behavior / synchrony.
|
||||||
|
const float AVATAR_HEAD_PITCH_MAGNIFY = 1.0f;
|
||||||
|
const float AVATAR_HEAD_YAW_MAGNIFY = 1.0f;
|
||||||
|
const float AVATAR_HEAD_ROLL_MAGNIFY = 1.0f;
|
||||||
|
_head.setPitch(estimatedRotation.x * AVATAR_HEAD_PITCH_MAGNIFY);
|
||||||
|
_head.setYaw(estimatedRotation.y * AVATAR_HEAD_YAW_MAGNIFY);
|
||||||
|
_head.setRoll(estimatedRotation.z * AVATAR_HEAD_ROLL_MAGNIFY);
|
||||||
_head.setCameraFollowsHead(gyroLook);
|
_head.setCameraFollowsHead(gyroLook);
|
||||||
|
|
||||||
// Update torso lean distance based on accelerometer data
|
// Update torso lean distance based on accelerometer data
|
||||||
|
@ -391,7 +395,7 @@ void Avatar::updateThrust(float deltaTime, Transmitter * transmitter) {
|
||||||
//
|
//
|
||||||
// Gather thrust information from keyboard and sensors to apply to avatar motion
|
// Gather thrust information from keyboard and sensors to apply to avatar motion
|
||||||
//
|
//
|
||||||
glm::quat orientation = getHead().getOrientation();
|
glm::quat orientation = getHead().getCameraOrientation();
|
||||||
glm::vec3 front = orientation * IDENTITY_FRONT;
|
glm::vec3 front = orientation * IDENTITY_FRONT;
|
||||||
glm::vec3 right = orientation * IDENTITY_RIGHT;
|
glm::vec3 right = orientation * IDENTITY_RIGHT;
|
||||||
glm::vec3 up = orientation * IDENTITY_UP;
|
glm::vec3 up = orientation * IDENTITY_UP;
|
||||||
|
@ -493,14 +497,17 @@ void Avatar::follow(Avatar* leadingAvatar) {
|
||||||
|
|
||||||
_leadingAvatar = leadingAvatar;
|
_leadingAvatar = leadingAvatar;
|
||||||
if (_leadingAvatar != NULL) {
|
if (_leadingAvatar != NULL) {
|
||||||
|
_leaderID = leadingAvatar->getOwningNode()->getNodeID();
|
||||||
_stringLength = glm::length(_position - _leadingAvatar->getPosition()) / _scale;
|
_stringLength = glm::length(_position - _leadingAvatar->getPosition()) / _scale;
|
||||||
if (_stringLength > MAX_STRING_LENGTH) {
|
if (_stringLength > MAX_STRING_LENGTH) {
|
||||||
_stringLength = MAX_STRING_LENGTH;
|
_stringLength = MAX_STRING_LENGTH;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
_leaderID = UNKNOWN_NODE_ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
void Avatar::simulate(float deltaTime, Transmitter* transmitter, float gyroCameraSensitivity) {
|
||||||
|
|
||||||
glm::quat orientation = getOrientation();
|
glm::quat orientation = getOrientation();
|
||||||
glm::vec3 front = orientation * IDENTITY_FRONT;
|
glm::vec3 front = orientation * IDENTITY_FRONT;
|
||||||
|
@ -623,9 +630,12 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
_velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime);
|
_velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateCollisionWithEnvironment(deltaTime);
|
|
||||||
updateCollisionWithVoxels(deltaTime);
|
if (_isCollisionsOn) {
|
||||||
updateAvatarCollisions(deltaTime);
|
updateCollisionWithEnvironment(deltaTime);
|
||||||
|
updateCollisionWithVoxels(deltaTime);
|
||||||
|
updateAvatarCollisions(deltaTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update body balls
|
// update body balls
|
||||||
|
@ -633,7 +643,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
|
|
||||||
|
|
||||||
// test for avatar collision response with the big sphere
|
// test for avatar collision response with the big sphere
|
||||||
if (usingBigSphereCollisionTest) {
|
if (usingBigSphereCollisionTest && _isCollisionsOn) {
|
||||||
updateCollisionWithSphere(_TEST_bigSpherePosition, _TEST_bigSphereRadius, deltaTime);
|
updateCollisionWithSphere(_TEST_bigSpherePosition, _TEST_bigSphereRadius, deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +757,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
_head.setPosition(_bodyBall[ BODY_BALL_HEAD_BASE ].position);
|
_head.setPosition(_bodyBall[ BODY_BALL_HEAD_BASE ].position);
|
||||||
_head.setScale(_scale);
|
_head.setScale(_scale);
|
||||||
_head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]));
|
_head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]));
|
||||||
_head.simulate(deltaTime, isMyAvatar());
|
_head.simulate(deltaTime, isMyAvatar(), gyroCameraSensitivity);
|
||||||
_hand.simulate(deltaTime, isMyAvatar());
|
_hand.simulate(deltaTime, isMyAvatar());
|
||||||
|
|
||||||
|
|
||||||
|
@ -1209,6 +1219,15 @@ void Avatar::render(bool lookingInMirror, bool renderAvatarBalls) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Avatar::renderScreenTint(ScreenTintLayer layer) {
|
||||||
|
|
||||||
|
if (layer == SCREEN_TINT_BEFORE_AVATARS) {
|
||||||
|
if (_hand.isRaveGloveActive()) {
|
||||||
|
_hand.renderRaveGloveStage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Avatar::resetBodyBalls() {
|
void Avatar::resetBodyBalls() {
|
||||||
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||||
|
|
||||||
|
@ -1374,6 +1393,17 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
||||||
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||||
float alpha = getBallRenderAlpha(b, lookingInMirror);
|
float alpha = getBallRenderAlpha(b, lookingInMirror);
|
||||||
|
|
||||||
|
// When in rave glove mode, don't show the arms at all.
|
||||||
|
if (_hand.isRaveGloveActive()) {
|
||||||
|
if (b == BODY_BALL_LEFT_ELBOW
|
||||||
|
|| b == BODY_BALL_LEFT_WRIST
|
||||||
|
|| b == BODY_BALL_LEFT_FINGERTIPS
|
||||||
|
|| b == BODY_BALL_RIGHT_ELBOW
|
||||||
|
|| b == BODY_BALL_RIGHT_WRIST
|
||||||
|
|| b == BODY_BALL_RIGHT_FINGERTIPS) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Always render other people, and render myself when beyond threshold distance
|
// Always render other people, and render myself when beyond threshold distance
|
||||||
if (b == BODY_BALL_HEAD_BASE) { // the head is rendered as a special
|
if (b == BODY_BALL_HEAD_BASE) { // the head is rendered as a special
|
||||||
if (alpha > 0.0f) {
|
if (alpha > 0.0f) {
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
|
|
||||||
|
|
||||||
static const float MAX_SCALE = 5.f;
|
static const float MAX_SCALE = 10.f;
|
||||||
static const float MIN_SCALE = .5f;
|
static const float MIN_SCALE = .5f;
|
||||||
static const float SCALING_RATIO = .05f;
|
static const float SCALING_RATIO = .05f;
|
||||||
static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1
|
static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1
|
||||||
|
@ -112,6 +112,15 @@ enum AvatarMode
|
||||||
NUM_AVATAR_MODES
|
NUM_AVATAR_MODES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ScreenTintLayer
|
||||||
|
{
|
||||||
|
SCREEN_TINT_BEFORE_LANDSCAPE = 0,
|
||||||
|
SCREEN_TINT_BEFORE_AVATARS,
|
||||||
|
SCREEN_TINT_BEFORE_MY_AVATAR,
|
||||||
|
SCREEN_TINT_AFTER_MY_AVATAR,
|
||||||
|
NUM_SCREEN_TINT_LAYERS
|
||||||
|
};
|
||||||
|
|
||||||
class Avatar : public AvatarData {
|
class Avatar : public AvatarData {
|
||||||
public:
|
public:
|
||||||
Avatar(Node* owningNode = NULL);
|
Avatar(Node* owningNode = NULL);
|
||||||
|
@ -119,16 +128,15 @@ public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void reset();
|
void reset();
|
||||||
void simulate(float deltaTime, Transmitter* transmitter);
|
void simulate(float deltaTime, Transmitter* transmitter, float gyroCameraSensitivity);
|
||||||
void updateThrust(float deltaTime, Transmitter * transmitter);
|
void updateThrust(float deltaTime, Transmitter * transmitter);
|
||||||
void follow(Avatar* leadingAvatar);
|
void follow(Avatar* leadingAvatar);
|
||||||
void updateFromGyrosAndOrWebcam(bool gyroLook,
|
void updateFromGyrosAndOrWebcam(bool gyroLook,
|
||||||
const glm::vec3& amplifyAngle,
|
|
||||||
float yawFromTouch,
|
|
||||||
float pitchFromTouch);
|
float pitchFromTouch);
|
||||||
void addBodyYaw(float bodyYaw) {_bodyYaw += bodyYaw;};
|
void addBodyYaw(float bodyYaw) {_bodyYaw += bodyYaw;};
|
||||||
void addBodyYawDelta(float bodyYawDelta) {_bodyYawDelta += bodyYawDelta;}
|
void addBodyYawDelta(float bodyYawDelta) {_bodyYawDelta += bodyYawDelta;}
|
||||||
void render(bool lookingInMirror, bool renderAvatarBalls);
|
void render(bool lookingInMirror, bool renderAvatarBalls);
|
||||||
|
void renderScreenTint(ScreenTintLayer layer);
|
||||||
|
|
||||||
//setters
|
//setters
|
||||||
void setMousePressed (bool mousePressed ) { _mousePressed = mousePressed;}
|
void setMousePressed (bool mousePressed ) { _mousePressed = mousePressed;}
|
||||||
|
@ -142,6 +150,7 @@ public:
|
||||||
void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction);
|
void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction);
|
||||||
void setOrientation (const glm::quat& orientation);
|
void setOrientation (const glm::quat& orientation);
|
||||||
void setNewScale (const float scale);
|
void setNewScale (const float scale);
|
||||||
|
void setWantCollisionsOn (bool wantCollisionsOn ) { _isCollisionsOn = wantCollisionsOn; }
|
||||||
|
|
||||||
//getters
|
//getters
|
||||||
bool isInitialized () const { return _initialized;}
|
bool isInitialized () const { return _initialized;}
|
||||||
|
@ -263,6 +272,7 @@ private:
|
||||||
glm::vec3 _lastCollisionPosition;
|
glm::vec3 _lastCollisionPosition;
|
||||||
bool _speedBrakes;
|
bool _speedBrakes;
|
||||||
bool _isThrustOn;
|
bool _isThrustOn;
|
||||||
|
bool _isCollisionsOn;
|
||||||
|
|
||||||
Avatar* _leadingAvatar;
|
Avatar* _leadingAvatar;
|
||||||
float _stringLength;
|
float _stringLength;
|
||||||
|
|
|
@ -54,8 +54,8 @@ void Hand::reset() {
|
||||||
void Hand::simulate(float deltaTime, bool isMine) {
|
void Hand::simulate(float deltaTime, bool isMine) {
|
||||||
|
|
||||||
if (_isRaveGloveActive) {
|
if (_isRaveGloveActive) {
|
||||||
if (_raveGloveEffectsModeChanged) {
|
if (_raveGloveEffectsModeChanged && _raveGloveInitialized) {
|
||||||
setRaveGloveMode(_raveGloveEffectsMode);
|
activateNewRaveGloveMode();
|
||||||
_raveGloveEffectsModeChanged = false;
|
_raveGloveEffectsModeChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,10 +64,10 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hand::calculateGeometry() {
|
void Hand::calculateGeometry() {
|
||||||
glm::vec3 offset(0.2, -0.2, -0.3); // place the hand in front of the face where we can see it
|
const glm::vec3 leapHandsOffsetFromFace(0.0, -0.2, -0.3); // place the hand in front of the face where we can see it
|
||||||
|
|
||||||
Head& head = _owningAvatar->getHead();
|
Head& head = _owningAvatar->getHead();
|
||||||
_basePosition = head.getPosition() + head.getOrientation() * offset;
|
_basePosition = head.getPosition() + head.getOrientation() * leapHandsOffsetFromFace;
|
||||||
_baseOrientation = head.getOrientation();
|
_baseOrientation = head.getOrientation();
|
||||||
|
|
||||||
// generate finger tip balls....
|
// generate finger tip balls....
|
||||||
|
@ -154,8 +154,10 @@ void Hand::render(bool lookingInMirror) {
|
||||||
|
|
||||||
if ( SHOW_LEAP_HAND ) {
|
if ( SHOW_LEAP_HAND ) {
|
||||||
//renderLeapHands();
|
//renderLeapHands();
|
||||||
renderLeapFingerTrails();
|
if (!isRaveGloveActive()) {
|
||||||
renderLeapHandSpheres();
|
renderLeapFingerTrails();
|
||||||
|
renderLeapHandSpheres();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +174,7 @@ void Hand::renderRaveGloveStage() {
|
||||||
glm::vec3 v3 = headOrientation * (glm::vec3(-1.0f, 1.0f, 0.0f) * scale) + vc;
|
glm::vec3 v3 = headOrientation * (glm::vec3(-1.0f, 1.0f, 0.0f) * scale) + vc;
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBegin(GL_TRIANGLE_FAN);
|
glBegin(GL_TRIANGLE_FAN);
|
||||||
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
@ -183,6 +186,7 @@ void Hand::renderRaveGloveStage() {
|
||||||
glVertex3fv((float*)&v3);
|
glVertex3fv((float*)&v3);
|
||||||
glVertex3fv((float*)&v0);
|
glVertex3fv((float*)&v0);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,6 +356,7 @@ void Hand::updateRaveGloveParticles(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_FIRE);
|
setRaveGloveMode(RAVE_GLOVE_EFFECTS_MODE_FIRE);
|
||||||
|
activateNewRaveGloveMode();
|
||||||
_raveGloveParticleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f));
|
_raveGloveParticleSystem.setUpDirection(glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
_raveGloveInitialized = true;
|
_raveGloveInitialized = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -359,11 +364,14 @@ void Hand::updateRaveGloveParticles(float deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The rave glove mode has changed, so activate the effects.
|
||||||
|
void Hand::activateNewRaveGloveMode() {
|
||||||
|
|
||||||
void Hand::setRaveGloveMode(int mode) {
|
if (!_raveGloveInitialized) {
|
||||||
|
return;
|
||||||
_raveGloveMode = mode;
|
}
|
||||||
|
|
||||||
|
int mode = _raveGloveEffectsMode;
|
||||||
_raveGloveParticleSystem.killAllParticles();
|
_raveGloveParticleSystem.killAllParticles();
|
||||||
|
|
||||||
for ( int f = 0; f< NUM_FINGERS; f ++ ) {
|
for ( int f = 0; f< NUM_FINGERS; f ++ ) {
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
void reset();
|
void reset();
|
||||||
void simulate(float deltaTime, bool isMine);
|
void simulate(float deltaTime, bool isMine);
|
||||||
void render(bool lookingInMirror);
|
void render(bool lookingInMirror);
|
||||||
|
void renderRaveGloveStage();
|
||||||
|
|
||||||
void setBallColor (glm::vec3 ballColor ) { _ballColor = ballColor; }
|
void setBallColor (glm::vec3 ballColor ) { _ballColor = ballColor; }
|
||||||
void updateRaveGloveParticles(float deltaTime);
|
void updateRaveGloveParticles(float deltaTime);
|
||||||
|
@ -60,8 +61,6 @@ private:
|
||||||
float _raveGloveClock;
|
float _raveGloveClock;
|
||||||
bool _raveGloveInitialized;
|
bool _raveGloveInitialized;
|
||||||
int _raveGloveEmitter[NUM_FINGERS];
|
int _raveGloveEmitter[NUM_FINGERS];
|
||||||
int _raveGloveEffectsMode;
|
|
||||||
bool _raveGloveEffectsModeChanged;
|
|
||||||
|
|
||||||
Avatar* _owningAvatar;
|
Avatar* _owningAvatar;
|
||||||
float _renderAlpha;
|
float _renderAlpha;
|
||||||
|
@ -74,9 +73,8 @@ private:
|
||||||
void setLeapHands(const std::vector<glm::vec3>& handPositions,
|
void setLeapHands(const std::vector<glm::vec3>& handPositions,
|
||||||
const std::vector<glm::vec3>& handNormals);
|
const std::vector<glm::vec3>& handNormals);
|
||||||
|
|
||||||
virtual void setRaveGloveMode(int mode);
|
void activateNewRaveGloveMode();
|
||||||
|
|
||||||
void renderRaveGloveStage();
|
|
||||||
void renderLeapHandSpheres();
|
void renderLeapHandSpheres();
|
||||||
void renderLeapHands();
|
void renderLeapHands();
|
||||||
void renderLeapHand(PalmData& hand);
|
void renderLeapHand(PalmData& hand);
|
||||||
|
|
|
@ -84,6 +84,7 @@ Head::Head(Avatar* owningAvatar) :
|
||||||
_rightEyeBlinkVelocity(0.0f),
|
_rightEyeBlinkVelocity(0.0f),
|
||||||
_timeWithoutTalking(0.0f),
|
_timeWithoutTalking(0.0f),
|
||||||
_cameraPitch(_pitch),
|
_cameraPitch(_pitch),
|
||||||
|
_mousePitch(0.f),
|
||||||
_cameraYaw(_yaw),
|
_cameraYaw(_yaw),
|
||||||
_isCameraMoving(false),
|
_isCameraMoving(false),
|
||||||
_cameraFollowsHead(false),
|
_cameraFollowsHead(false),
|
||||||
|
@ -145,7 +146,7 @@ void Head::resetHairPhysics() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Head::simulate(float deltaTime, bool isMine) {
|
void Head::simulate(float deltaTime, bool isMine, float gyroCameraSensitivity) {
|
||||||
|
|
||||||
// Update eye saccades
|
// Update eye saccades
|
||||||
const float AVERAGE_MICROSACCADE_INTERVAL = 0.50f;
|
const float AVERAGE_MICROSACCADE_INTERVAL = 0.50f;
|
||||||
|
@ -227,15 +228,18 @@ void Head::simulate(float deltaTime, bool isMine) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update camera pitch and yaw independently from motion of head (for gyro-based interface)
|
// Update camera pitch and yaw independently from motion of head (for gyro-based interface)
|
||||||
if (isMine && _cameraFollowsHead) {
|
if (isMine && _cameraFollowsHead && (gyroCameraSensitivity > 0.f)) {
|
||||||
// If we are using gyros and using gyroLook, have the camera follow head but with a null region
|
// If we are using gyros and using gyroLook, have the camera follow head but with a null region
|
||||||
// to create stable rendering view with small head movements.
|
// to create stable rendering view with small head movements.
|
||||||
const float CAMERA_FOLLOW_HEAD_RATE_START = 0.01f;
|
const float CAMERA_FOLLOW_HEAD_RATE_START = 0.1f;
|
||||||
const float CAMERA_FOLLOW_HEAD_RATE_MAX = 0.5f;
|
const float CAMERA_FOLLOW_HEAD_RATE_MAX = 1.0f;
|
||||||
const float CAMERA_FOLLOW_HEAD_RATE_RAMP_RATE = 1.05f;
|
const float CAMERA_FOLLOW_HEAD_RATE_RAMP_RATE = 1.05f;
|
||||||
const float CAMERA_STOP_TOLERANCE_DEGREES = 0.5f;
|
const float CAMERA_STOP_TOLERANCE_DEGREES = 0.5f;
|
||||||
const float CAMERA_PITCH_START_TOLERANCE_DEGREES = 20.0f;
|
const float PITCH_START_RANGE = 20.f;
|
||||||
const float CAMERA_YAW_START_TOLERANCE_DEGREES = 10.0f;
|
const float YAW_START_RANGE = 10.f;
|
||||||
|
float pitchStartTolerance = PITCH_START_RANGE * (1.f - gyroCameraSensitivity);
|
||||||
|
float yawStartTolerance = YAW_START_RANGE * (1.f - gyroCameraSensitivity);
|
||||||
|
|
||||||
float cameraHeadAngleDifference = glm::length(glm::vec2(_pitch - _cameraPitch, _yaw - _cameraYaw));
|
float cameraHeadAngleDifference = glm::length(glm::vec2(_pitch - _cameraPitch, _yaw - _cameraYaw));
|
||||||
if (_isCameraMoving) {
|
if (_isCameraMoving) {
|
||||||
_cameraFollowHeadRate = glm::clamp(_cameraFollowHeadRate * CAMERA_FOLLOW_HEAD_RATE_RAMP_RATE,
|
_cameraFollowHeadRate = glm::clamp(_cameraFollowHeadRate * CAMERA_FOLLOW_HEAD_RATE_RAMP_RATE,
|
||||||
|
@ -248,17 +252,13 @@ void Head::simulate(float deltaTime, bool isMine) {
|
||||||
_isCameraMoving = false;
|
_isCameraMoving = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((fabs(_pitch - _cameraPitch) > CAMERA_PITCH_START_TOLERANCE_DEGREES) ||
|
if ((fabs(_pitch - _cameraPitch) > pitchStartTolerance) ||
|
||||||
(fabs(_yaw - _cameraYaw) > CAMERA_YAW_START_TOLERANCE_DEGREES)) {
|
(fabs(_yaw - _cameraYaw) > yawStartTolerance)) {
|
||||||
_isCameraMoving = true;
|
_isCameraMoving = true;
|
||||||
_cameraFollowHeadRate = CAMERA_FOLLOW_HEAD_RATE_START;
|
_cameraFollowHeadRate = CAMERA_FOLLOW_HEAD_RATE_START;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// Camera always locked to head
|
|
||||||
_cameraPitch = _pitch;
|
|
||||||
_cameraYaw = _yaw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::calculateGeometry() {
|
void Head::calculateGeometry() {
|
||||||
|
@ -338,7 +338,7 @@ void Head::setScale (float scale) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::createMohawk() {
|
void Head::createMohawk() {
|
||||||
uint16_t nodeId = 0;
|
uint16_t nodeId = UNKNOWN_NODE_ID;
|
||||||
if (_owningAvatar->getOwningNode()) {
|
if (_owningAvatar->getOwningNode()) {
|
||||||
nodeId = _owningAvatar->getOwningNode()->getNodeID();
|
nodeId = _owningAvatar->getOwningNode()->getNodeID();
|
||||||
} else {
|
} else {
|
||||||
|
@ -428,7 +428,7 @@ glm::quat Head::getOrientation() const {
|
||||||
glm::quat Head::getCameraOrientation () const {
|
glm::quat Head::getCameraOrientation () const {
|
||||||
Avatar* owningAvatar = static_cast<Avatar*>(_owningAvatar);
|
Avatar* owningAvatar = static_cast<Avatar*>(_owningAvatar);
|
||||||
return owningAvatar->getWorldAlignedOrientation()
|
return owningAvatar->getWorldAlignedOrientation()
|
||||||
* glm::quat(glm::radians(glm::vec3(_cameraPitch, _cameraYaw, 0.0f)));
|
* glm::quat(glm::radians(glm::vec3(_cameraPitch + _mousePitch, _cameraYaw, 0.0f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::renderHeadSphere() {
|
void Head::renderHeadSphere() {
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void reset();
|
void reset();
|
||||||
void simulate(float deltaTime, bool isMine);
|
void simulate(float deltaTime, bool isMine, float gyroCameraSensitivity);
|
||||||
void render(float alpha);
|
void render(float alpha);
|
||||||
void renderMohawk();
|
void renderMohawk();
|
||||||
|
|
||||||
|
@ -57,6 +57,8 @@ public:
|
||||||
|
|
||||||
void setCameraFollowsHead(bool cameraFollowsHead) { _cameraFollowsHead = cameraFollowsHead; }
|
void setCameraFollowsHead(bool cameraFollowsHead) { _cameraFollowsHead = cameraFollowsHead; }
|
||||||
|
|
||||||
|
void setMousePitch(float mousePitch) { _mousePitch = mousePitch; }
|
||||||
|
|
||||||
glm::quat getOrientation() const;
|
glm::quat getOrientation() const;
|
||||||
glm::quat getCameraOrientation () const;
|
glm::quat getCameraOrientation () const;
|
||||||
|
|
||||||
|
@ -123,6 +125,7 @@ private:
|
||||||
float _rightEyeBlinkVelocity;
|
float _rightEyeBlinkVelocity;
|
||||||
float _timeWithoutTalking;
|
float _timeWithoutTalking;
|
||||||
float _cameraPitch; // Used to position the camera differently from the head
|
float _cameraPitch; // Used to position the camera differently from the head
|
||||||
|
float _mousePitch;
|
||||||
float _cameraYaw;
|
float _cameraYaw;
|
||||||
bool _isCameraMoving;
|
bool _isCameraMoving;
|
||||||
bool _cameraFollowsHead;
|
bool _cameraFollowsHead;
|
||||||
|
|
|
@ -28,6 +28,7 @@ AvatarData::AvatarData(Node* owningNode) :
|
||||||
_bodyPitch(0.0),
|
_bodyPitch(0.0),
|
||||||
_bodyRoll(0.0),
|
_bodyRoll(0.0),
|
||||||
_newScale(1.0f),
|
_newScale(1.0f),
|
||||||
|
_leaderID(UNKNOWN_NODE_ID),
|
||||||
_handState(0),
|
_handState(0),
|
||||||
_cameraPosition(0,0,0),
|
_cameraPosition(0,0,0),
|
||||||
_cameraOrientation(),
|
_cameraOrientation(),
|
||||||
|
@ -91,8 +92,14 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw);
|
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw);
|
||||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch);
|
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch);
|
||||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll);
|
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll);
|
||||||
|
|
||||||
|
// Body scale
|
||||||
destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _newScale);
|
destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _newScale);
|
||||||
|
|
||||||
|
// Follow mode info
|
||||||
|
memcpy(destinationBuffer, &_leaderID, sizeof(uint16_t));
|
||||||
|
destinationBuffer += sizeof(uint16_t);
|
||||||
|
|
||||||
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_yaw);
|
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_yaw);
|
||||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_pitch);
|
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_pitch);
|
||||||
|
@ -188,8 +195,14 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyYaw);
|
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyYaw);
|
||||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyPitch);
|
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyPitch);
|
||||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyRoll);
|
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyRoll);
|
||||||
|
|
||||||
|
// Body scale
|
||||||
sourceBuffer += unpackFloatRatioFromTwoByte( sourceBuffer, _newScale);
|
sourceBuffer += unpackFloatRatioFromTwoByte( sourceBuffer, _newScale);
|
||||||
|
|
||||||
|
// Follow mode info
|
||||||
|
memcpy(&_leaderID, sourceBuffer, sizeof(uint16_t));
|
||||||
|
sourceBuffer += sizeof(uint16_t);
|
||||||
|
|
||||||
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||||
float headYaw, headPitch, headRoll;
|
float headYaw, headPitch, headRoll;
|
||||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw);
|
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw);
|
||||||
|
|
|
@ -92,10 +92,11 @@ public:
|
||||||
const std::string& chatMessage () const { return _chatMessage; }
|
const std::string& chatMessage () const { return _chatMessage; }
|
||||||
|
|
||||||
// related to Voxel Sending strategies
|
// related to Voxel Sending strategies
|
||||||
bool getWantColor() const { return _wantColor; }
|
bool getWantColor() const { return _wantColor; }
|
||||||
bool getWantDelta() const { return _wantDelta; }
|
bool getWantDelta() const { return _wantDelta; }
|
||||||
bool getWantLowResMoving() const { return _wantLowResMoving; }
|
bool getWantLowResMoving() const { return _wantLowResMoving; }
|
||||||
bool getWantOcclusionCulling() const { return _wantOcclusionCulling; }
|
bool getWantOcclusionCulling() const { return _wantOcclusionCulling; }
|
||||||
|
uint16_t getLeaderID() const { return _leaderID; }
|
||||||
|
|
||||||
void setWantColor(bool wantColor) { _wantColor = wantColor; }
|
void setWantColor(bool wantColor) { _wantColor = wantColor; }
|
||||||
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
|
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
|
||||||
|
@ -118,8 +119,13 @@ protected:
|
||||||
float _bodyYaw;
|
float _bodyYaw;
|
||||||
float _bodyPitch;
|
float _bodyPitch;
|
||||||
float _bodyRoll;
|
float _bodyRoll;
|
||||||
|
|
||||||
|
// Body scale
|
||||||
float _newScale;
|
float _newScale;
|
||||||
|
|
||||||
|
// Following mode infos
|
||||||
|
uint16_t _leaderID;
|
||||||
|
|
||||||
// Hand state (are we grabbing something or not)
|
// Hand state (are we grabbing something or not)
|
||||||
char _handState;
|
char _handState;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@ HandData::HandData(AvatarData* owningAvatar) :
|
||||||
_baseOrientation(0.0f, 0.0f, 0.0f, 1.0f),
|
_baseOrientation(0.0f, 0.0f, 0.0f, 1.0f),
|
||||||
_owningAvatarData(owningAvatar),
|
_owningAvatarData(owningAvatar),
|
||||||
_isRaveGloveActive(false),
|
_isRaveGloveActive(false),
|
||||||
_raveGloveMode(RAVE_GLOVE_EFFECTS_MODE_THROBBING_COLOR)
|
_raveGloveEffectsMode(RAVE_GLOVE_EFFECTS_MODE_THROBBING_COLOR),
|
||||||
|
_raveGloveEffectsModeChanged(false)
|
||||||
{
|
{
|
||||||
// Start with two palms
|
// Start with two palms
|
||||||
addNewPalm();
|
addNewPalm();
|
||||||
|
@ -160,8 +161,9 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
setRaveGloveActive((gloveFlags & GLOVE_FLAG_RAVE) != 0);
|
setRaveGloveActive((gloveFlags & GLOVE_FLAG_RAVE) != 0);
|
||||||
// This is disabled for crash tracing.
|
if (numHands > 0) {
|
||||||
// setRaveGloveMode(effectsMode);
|
setRaveGloveMode(effectsMode);
|
||||||
|
}
|
||||||
|
|
||||||
// One byte for error checking safety.
|
// One byte for error checking safety.
|
||||||
unsigned char requiredLength = (unsigned char)(sourceBuffer - startPosition);
|
unsigned char requiredLength = (unsigned char)(sourceBuffer - startPosition);
|
||||||
|
@ -171,6 +173,13 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) {
|
||||||
return sourceBuffer - startPosition;
|
return sourceBuffer - startPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandData::setRaveGloveMode(int effectsMode) {
|
||||||
|
if (effectsMode != _raveGloveEffectsMode) {
|
||||||
|
_raveGloveEffectsModeChanged = true;
|
||||||
|
}
|
||||||
|
_raveGloveEffectsMode = effectsMode;
|
||||||
|
}
|
||||||
|
|
||||||
void HandData::setFingerTrailLength(unsigned int length) {
|
void HandData::setFingerTrailLength(unsigned int length) {
|
||||||
for (size_t i = 0; i < getNumPalms(); ++i) {
|
for (size_t i = 0; i < getNumPalms(); ++i) {
|
||||||
PalmData& palm = getPalms()[i];
|
PalmData& palm = getPalms()[i];
|
||||||
|
|
|
@ -70,9 +70,9 @@ public:
|
||||||
int decodeRemoteData(unsigned char* sourceBuffer);
|
int decodeRemoteData(unsigned char* sourceBuffer);
|
||||||
|
|
||||||
void setRaveGloveActive(bool active) { _isRaveGloveActive = active; }
|
void setRaveGloveActive(bool active) { _isRaveGloveActive = active; }
|
||||||
virtual void setRaveGloveMode(int effectsMode) { _raveGloveMode = effectsMode; }
|
void setRaveGloveMode(int effectsMode);
|
||||||
bool isRaveGloveActive() const { return _isRaveGloveActive; }
|
bool isRaveGloveActive() const { return _isRaveGloveActive; }
|
||||||
int getRaveGloveMode() { return _raveGloveMode; }
|
int getRaveGloveMode() { return _raveGloveEffectsMode; }
|
||||||
|
|
||||||
friend class AvatarData;
|
friend class AvatarData;
|
||||||
protected:
|
protected:
|
||||||
|
@ -81,7 +81,8 @@ protected:
|
||||||
AvatarData* _owningAvatarData;
|
AvatarData* _owningAvatarData;
|
||||||
std::vector<PalmData> _palms;
|
std::vector<PalmData> _palms;
|
||||||
bool _isRaveGloveActive;
|
bool _isRaveGloveActive;
|
||||||
int _raveGloveMode;
|
int _raveGloveEffectsMode;
|
||||||
|
bool _raveGloveEffectsModeChanged;
|
||||||
private:
|
private:
|
||||||
// privatize copy ctor and assignment operator so copies of this object cannot be made
|
// privatize copy ctor and assignment operator so copies of this object cannot be made
|
||||||
HandData(const HandData&);
|
HandData(const HandData&);
|
||||||
|
|
|
@ -435,6 +435,8 @@ void NodeList::addNodeToList(Node* newNode) {
|
||||||
++_numNodes;
|
++_numNodes;
|
||||||
|
|
||||||
qDebug() << "Added" << *newNode << "\n";
|
qDebug() << "Added" << *newNode << "\n";
|
||||||
|
|
||||||
|
notifyHooksOfAddedNode(newNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned NodeList::broadcastToNodes(unsigned char *broadcastData, size_t dataBytes, const char* nodeTypes, int numNodeTypes) {
|
unsigned NodeList::broadcastToNodes(unsigned char *broadcastData, size_t dataBytes, const char* nodeTypes, int numNodeTypes) {
|
||||||
|
@ -476,7 +478,7 @@ Node* NodeList::soloNodeOfType(char nodeType) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *removeSilentNodes(void *args) {
|
void* removeSilentNodes(void *args) {
|
||||||
NodeList* nodeList = (NodeList*) args;
|
NodeList* nodeList = (NodeList*) args;
|
||||||
uint64_t checkTimeUSecs;
|
uint64_t checkTimeUSecs;
|
||||||
int sleepTime;
|
int sleepTime;
|
||||||
|
@ -490,6 +492,8 @@ void *removeSilentNodes(void *args) {
|
||||||
|
|
||||||
qDebug() << "Killed" << *node << "\n";
|
qDebug() << "Killed" << *node << "\n";
|
||||||
|
|
||||||
|
nodeList->notifyHooksOfKilledNode(&*node);
|
||||||
|
|
||||||
node->setAlive(false);
|
node->setAlive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -619,3 +623,30 @@ void NodeListIterator::skipDeadAndStopIncrement() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeList::addHook(NodeListHook* hook) {
|
||||||
|
_hooks.push_back(hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeList::removeHook(NodeListHook* hook) {
|
||||||
|
for (int i = 0; i < _hooks.size(); i++) {
|
||||||
|
if (_hooks[i] == hook) {
|
||||||
|
_hooks.erase(_hooks.begin() + i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeList::notifyHooksOfAddedNode(Node* node) {
|
||||||
|
for (int i = 0; i < _hooks.size(); i++) {
|
||||||
|
printf("NodeList::notifyHooksOfAddedNode() i=%d\n", i);
|
||||||
|
_hooks[i]->nodeAdded(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeList::notifyHooksOfKilledNode(Node* node) {
|
||||||
|
for (int i = 0; i < _hooks.size(); i++) {
|
||||||
|
printf("NodeList::notifyHooksOfKilledNode() i=%d\n", i);
|
||||||
|
_hooks[i]->nodeKilled(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -45,6 +45,14 @@ const int UNKNOWN_NODE_ID = -1;
|
||||||
|
|
||||||
class NodeListIterator;
|
class NodeListIterator;
|
||||||
|
|
||||||
|
// Callers who want to hook add/kill callbacks should implement this class
|
||||||
|
class NodeListHook {
|
||||||
|
public:
|
||||||
|
virtual void nodeAdded(Node* node) = 0;
|
||||||
|
virtual void nodeKilled(Node* node) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class NodeList {
|
class NodeList {
|
||||||
public:
|
public:
|
||||||
static NodeList* createInstance(char ownerType, unsigned int socketListenPort = NODE_SOCKET_LISTEN_PORT);
|
static NodeList* createInstance(char ownerType, unsigned int socketListenPort = NODE_SOCKET_LISTEN_PORT);
|
||||||
|
@ -66,7 +74,7 @@ public:
|
||||||
void setDomainIPToLocalhost();
|
void setDomainIPToLocalhost();
|
||||||
|
|
||||||
uint16_t getLastNodeID() const { return _lastNodeID; }
|
uint16_t getLastNodeID() const { return _lastNodeID; }
|
||||||
void increaseNodeID() { ++_lastNodeID; }
|
void increaseNodeID() { (++_lastNodeID == UNKNOWN_NODE_ID) ? ++_lastNodeID : _lastNodeID; }
|
||||||
|
|
||||||
uint16_t getOwnerID() const { return _ownerID; }
|
uint16_t getOwnerID() const { return _ownerID; }
|
||||||
void setOwnerID(uint16_t ownerID) { _ownerID = ownerID; }
|
void setOwnerID(uint16_t ownerID) { _ownerID = ownerID; }
|
||||||
|
@ -111,6 +119,12 @@ public:
|
||||||
void saveData(QSettings* settings);
|
void saveData(QSettings* settings);
|
||||||
|
|
||||||
friend class NodeListIterator;
|
friend class NodeListIterator;
|
||||||
|
|
||||||
|
void addHook(NodeListHook* hook);
|
||||||
|
void removeHook(NodeListHook* hook);
|
||||||
|
void notifyHooksOfAddedNode(Node* node);
|
||||||
|
void notifyHooksOfKilledNode(Node* node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static NodeList* _sharedInstance;
|
static NodeList* _sharedInstance;
|
||||||
|
|
||||||
|
@ -136,6 +150,8 @@ private:
|
||||||
|
|
||||||
void handlePingReply(sockaddr *nodeAddress);
|
void handlePingReply(sockaddr *nodeAddress);
|
||||||
void timePingReply(sockaddr *nodeAddress, unsigned char *packetData);
|
void timePingReply(sockaddr *nodeAddress, unsigned char *packetData);
|
||||||
|
|
||||||
|
std::vector<NodeListHook*> _hooks;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NodeListIterator : public std::iterator<std::input_iterator_tag, Node> {
|
class NodeListIterator : public std::iterator<std::input_iterator_tag, Node> {
|
||||||
|
|
|
@ -115,6 +115,27 @@ unsigned char * childOctalCode(unsigned char * parentOctalCode, char childNumber
|
||||||
return newCode;
|
return newCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void voxelDetailsForCode(unsigned char * octalCode, VoxelPositionSize& voxelPositionSize) {
|
||||||
|
float output[3];
|
||||||
|
memset(&output[0], 0, 3 * sizeof(float));
|
||||||
|
|
||||||
|
float currentScale = 1.0;
|
||||||
|
|
||||||
|
for (int i = 0; i < numberOfThreeBitSectionsInCode(octalCode); i++) {
|
||||||
|
currentScale *= 0.5;
|
||||||
|
int sectionIndex = sectionValue(octalCode + 1 + (3 * i / 8), (3 * i) % 8);
|
||||||
|
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
output[j] += currentScale * (int)oneAtBit(sectionIndex, 5 + j);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
voxelPositionSize.x = output[0];
|
||||||
|
voxelPositionSize.y = output[1];
|
||||||
|
voxelPositionSize.z = output[2];
|
||||||
|
voxelPositionSize.s = currentScale;
|
||||||
|
}
|
||||||
|
|
||||||
void copyFirstVertexForCode(unsigned char * octalCode, float* output) {
|
void copyFirstVertexForCode(unsigned char * octalCode, float* output) {
|
||||||
memset(output, 0, 3 * sizeof(float));
|
memset(output, 0, 3 * sizeof(float));
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,11 @@ bool isAncestorOf(unsigned char* possibleAncestor, unsigned char* possibleDescen
|
||||||
float * firstVertexForCode(unsigned char * octalCode);
|
float * firstVertexForCode(unsigned char * octalCode);
|
||||||
void copyFirstVertexForCode(unsigned char * octalCode, float* output);
|
void copyFirstVertexForCode(unsigned char * octalCode, float* output);
|
||||||
|
|
||||||
|
struct VoxelPositionSize {
|
||||||
|
float x, y, z, s;
|
||||||
|
};
|
||||||
|
void voxelDetailsForCode(unsigned char * octalCode, VoxelPositionSize& voxelPositionSize);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ILLEGAL_CODE = -2,
|
ILLEGAL_CODE = -2,
|
||||||
LESS_THAN = -1,
|
LESS_THAN = -1,
|
||||||
|
|
|
@ -20,11 +20,13 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case PACKET_TYPE_HEAD_DATA:
|
case PACKET_TYPE_HEAD_DATA:
|
||||||
return 3;
|
return 4;
|
||||||
|
|
||||||
case PACKET_TYPE_AVATAR_FACE_VIDEO:
|
case PACKET_TYPE_AVATAR_FACE_VIDEO:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
case PACKET_TYPE_VOXEL_STATS:
|
||||||
|
return 1;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ public:
|
||||||
|
|
||||||
bool writeToFile(const char* filename);
|
bool writeToFile(const char* filename);
|
||||||
bool readFromFile(const char* filename);
|
bool readFromFile(const char* filename);
|
||||||
|
|
||||||
|
unsigned char* getRootOctalCode() const { return _rootOctalCode; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void clear();
|
void clear();
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <OctalCode.h>
|
#include <OctalCode.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
// this is where the coordinate system is represented
|
// this is where the coordinate system is represented
|
||||||
const glm::vec3 IDENTITY_RIGHT = glm::vec3( 1.0f, 0.0f, 0.0f);
|
const glm::vec3 IDENTITY_RIGHT = glm::vec3( 1.0f, 0.0f, 0.0f);
|
||||||
|
|
|
@ -22,9 +22,17 @@ VoxelSceneStats::VoxelSceneStats() :
|
||||||
reset();
|
reset();
|
||||||
_isReadyToSend = false;
|
_isReadyToSend = false;
|
||||||
_isStarted = false;
|
_isStarted = false;
|
||||||
|
_jurisdictionRoot = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSceneStats::sceneStarted(bool isFullScene, bool isMoving, VoxelNode* root) {
|
VoxelSceneStats::~VoxelSceneStats() {
|
||||||
|
if (_jurisdictionRoot) {
|
||||||
|
delete[] _jurisdictionRoot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VoxelSceneStats::sceneStarted(bool isFullScene, bool isMoving, VoxelNode* root, JurisdictionMap* jurisdictionMap) {
|
||||||
reset(); // resets packet and voxel stats
|
reset(); // resets packet and voxel stats
|
||||||
_isStarted = true;
|
_isStarted = true;
|
||||||
_start = usecTimestampNow();
|
_start = usecTimestampNow();
|
||||||
|
@ -34,6 +42,19 @@ void VoxelSceneStats::sceneStarted(bool isFullScene, bool isMoving, VoxelNode* r
|
||||||
|
|
||||||
_isFullScene = isFullScene;
|
_isFullScene = isFullScene;
|
||||||
_isMoving = isMoving;
|
_isMoving = isMoving;
|
||||||
|
|
||||||
|
if (_jurisdictionRoot) {
|
||||||
|
delete[] _jurisdictionRoot;
|
||||||
|
_jurisdictionRoot = NULL;
|
||||||
|
}
|
||||||
|
if (jurisdictionMap) {
|
||||||
|
unsigned char* jurisdictionRoot = jurisdictionMap->getRootOctalCode();
|
||||||
|
if (jurisdictionRoot) {
|
||||||
|
int bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(jurisdictionRoot));
|
||||||
|
_jurisdictionRoot = new unsigned char[bytes];
|
||||||
|
memcpy(_jurisdictionRoot, jurisdictionRoot, bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSceneStats::sceneCompleted() {
|
void VoxelSceneStats::sceneCompleted() {
|
||||||
|
@ -273,6 +294,20 @@ int VoxelSceneStats::packIntoMessage(unsigned char* destinationBuffer, int avail
|
||||||
destinationBuffer += sizeof(_existsInPacketBitsWritten);
|
destinationBuffer += sizeof(_existsInPacketBitsWritten);
|
||||||
memcpy(destinationBuffer, &_treesRemoved, sizeof(_treesRemoved));
|
memcpy(destinationBuffer, &_treesRemoved, sizeof(_treesRemoved));
|
||||||
destinationBuffer += sizeof(_treesRemoved);
|
destinationBuffer += sizeof(_treesRemoved);
|
||||||
|
|
||||||
|
// add the root jurisdiction
|
||||||
|
if (_jurisdictionRoot) {
|
||||||
|
// copy the
|
||||||
|
int bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_jurisdictionRoot));
|
||||||
|
memcpy(destinationBuffer, &bytes, sizeof(bytes));
|
||||||
|
destinationBuffer += sizeof(bytes);
|
||||||
|
memcpy(destinationBuffer, _jurisdictionRoot, bytes);
|
||||||
|
destinationBuffer += bytes;
|
||||||
|
} else {
|
||||||
|
int bytes = 0;
|
||||||
|
memcpy(destinationBuffer, &bytes, sizeof(bytes));
|
||||||
|
destinationBuffer += sizeof(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
return destinationBuffer - bufferStart; // includes header!
|
return destinationBuffer - bufferStart; // includes header!
|
||||||
}
|
}
|
||||||
|
@ -363,6 +398,19 @@ int VoxelSceneStats::unpackFromMessage(unsigned char* sourceBuffer, int availabl
|
||||||
sourceBuffer += sizeof(_existsInPacketBitsWritten);
|
sourceBuffer += sizeof(_existsInPacketBitsWritten);
|
||||||
memcpy(&_treesRemoved, sourceBuffer, sizeof(_treesRemoved));
|
memcpy(&_treesRemoved, sourceBuffer, sizeof(_treesRemoved));
|
||||||
sourceBuffer += sizeof(_treesRemoved);
|
sourceBuffer += sizeof(_treesRemoved);
|
||||||
|
|
||||||
|
// read the root jurisdiction
|
||||||
|
int bytes = 0;
|
||||||
|
memcpy(&bytes, sourceBuffer, sizeof(bytes));
|
||||||
|
sourceBuffer += sizeof(bytes);
|
||||||
|
|
||||||
|
if (bytes == 0) {
|
||||||
|
_jurisdictionRoot = NULL;
|
||||||
|
} else {
|
||||||
|
_jurisdictionRoot = new unsigned char[bytes];
|
||||||
|
memcpy(_jurisdictionRoot, sourceBuffer, bytes);
|
||||||
|
sourceBuffer += bytes;
|
||||||
|
}
|
||||||
|
|
||||||
// running averages
|
// running averages
|
||||||
_elapsedAverage.updateAverage((float)_elapsed);
|
_elapsedAverage.updateAverage((float)_elapsed);
|
||||||
|
|
|
@ -12,14 +12,16 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
|
#include "JurisdictionMap.h"
|
||||||
|
|
||||||
class VoxelNode;
|
class VoxelNode;
|
||||||
|
|
||||||
class VoxelSceneStats {
|
class VoxelSceneStats {
|
||||||
public:
|
public:
|
||||||
VoxelSceneStats();
|
VoxelSceneStats();
|
||||||
|
~VoxelSceneStats();
|
||||||
void reset();
|
void reset();
|
||||||
void sceneStarted(bool fullScene, bool moving, VoxelNode* root);
|
void sceneStarted(bool fullScene, bool moving, VoxelNode* root, JurisdictionMap* jurisdictionMap);
|
||||||
void sceneCompleted();
|
void sceneCompleted();
|
||||||
|
|
||||||
void printDebugDetails();
|
void printDebugDetails();
|
||||||
|
@ -78,6 +80,9 @@ public:
|
||||||
ItemInfo& getItemInfo(int item) { return _ITEMS[item]; };
|
ItemInfo& getItemInfo(int item) { return _ITEMS[item]; };
|
||||||
char* getItemValue(int item);
|
char* getItemValue(int item);
|
||||||
|
|
||||||
|
unsigned char* getJurisdictionRoot() const { return _jurisdictionRoot; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _isReadyToSend;
|
bool _isReadyToSend;
|
||||||
unsigned char _statsMessage[MAX_PACKET_SIZE];
|
unsigned char _statsMessage[MAX_PACKET_SIZE];
|
||||||
|
@ -165,6 +170,8 @@ private:
|
||||||
static ItemInfo _ITEMS[];
|
static ItemInfo _ITEMS[];
|
||||||
static int const MAX_ITEM_VALUE_LENGTH = 128;
|
static int const MAX_ITEM_VALUE_LENGTH = 128;
|
||||||
char _itemValueBuffer[MAX_ITEM_VALUE_LENGTH];
|
char _itemValueBuffer[MAX_ITEM_VALUE_LENGTH];
|
||||||
|
|
||||||
|
unsigned char* _jurisdictionRoot;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__VoxelSceneStats__) */
|
#endif /* defined(__hifi__VoxelSceneStats__) */
|
||||||
|
|
|
@ -49,6 +49,7 @@ const float MAX_CUBE = 0.05f;
|
||||||
const int VOXEL_SEND_INTERVAL_USECS = 17 * 1000; // approximately 60fps
|
const int VOXEL_SEND_INTERVAL_USECS = 17 * 1000; // approximately 60fps
|
||||||
int PACKETS_PER_CLIENT_PER_INTERVAL = 20;
|
int PACKETS_PER_CLIENT_PER_INTERVAL = 20;
|
||||||
const int SENDING_TIME_TO_SPARE = 5 * 1000; // usec of sending interval to spare for calculating voxels
|
const int SENDING_TIME_TO_SPARE = 5 * 1000; // usec of sending interval to spare for calculating voxels
|
||||||
|
const int INTERVALS_PER_SECOND = 1000 * 1000 / VOXEL_SEND_INTERVAL_USECS;
|
||||||
|
|
||||||
const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4;
|
const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4;
|
||||||
|
|
||||||
|
@ -64,6 +65,7 @@ bool debugVoxelSending = false;
|
||||||
bool shouldShowAnimationDebug = false;
|
bool shouldShowAnimationDebug = false;
|
||||||
bool displayVoxelStats = false;
|
bool displayVoxelStats = false;
|
||||||
bool debugVoxelReceiving = false;
|
bool debugVoxelReceiving = false;
|
||||||
|
bool sendEnvironments = true;
|
||||||
|
|
||||||
EnvironmentData environmentData[3];
|
EnvironmentData environmentData[3];
|
||||||
|
|
||||||
|
@ -255,7 +257,7 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
|
||||||
|
|
||||||
// start tracking our stats
|
// start tracking our stats
|
||||||
bool isFullScene = (!viewFrustumChanged || !nodeData->getWantDelta()) && nodeData->getViewFrustumJustStoppedChanging();
|
bool isFullScene = (!viewFrustumChanged || !nodeData->getWantDelta()) && nodeData->getViewFrustumJustStoppedChanging();
|
||||||
nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged, ::serverTree.rootNode);
|
nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged, ::serverTree.rootNode, ::jurisdiction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have something in our nodeBag, then turn them into packets and send them out...
|
// If we have something in our nodeBag, then turn them into packets and send them out...
|
||||||
|
@ -265,7 +267,7 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
|
||||||
int packetsSentThisInterval = 0;
|
int packetsSentThisInterval = 0;
|
||||||
uint64_t start = usecTimestampNow();
|
uint64_t start = usecTimestampNow();
|
||||||
|
|
||||||
bool shouldSendEnvironments = shouldDo(ENVIRONMENT_SEND_INTERVAL_USECS, VOXEL_SEND_INTERVAL_USECS);
|
bool shouldSendEnvironments = ::sendEnvironments && shouldDo(ENVIRONMENT_SEND_INTERVAL_USECS, VOXEL_SEND_INTERVAL_USECS);
|
||||||
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - (shouldSendEnvironments ? 1 : 0)) {
|
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - (shouldSendEnvironments ? 1 : 0)) {
|
||||||
// Check to see if we're taking too long, and if so bail early...
|
// Check to see if we're taking too long, and if so bail early...
|
||||||
uint64_t now = usecTimestampNow();
|
uint64_t now = usecTimestampNow();
|
||||||
|
@ -473,6 +475,15 @@ int main(int argc, const char * argv[]) {
|
||||||
jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
|
jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// should we send environments? Default is yes, but this command line suppresses sending
|
||||||
|
const char* DONT_SEND_ENVIRONMENTS = "--dontSendEnvironments";
|
||||||
|
bool dontSendEnvironments = cmdOptionExists(argc, argv, DONT_SEND_ENVIRONMENTS);
|
||||||
|
if (dontSendEnvironments) {
|
||||||
|
printf("Sending environments suppressed...\n");
|
||||||
|
::sendEnvironments = false;
|
||||||
|
}
|
||||||
|
printf("Sending environments=%s\n", debug::valueOf(::sendEnvironments));
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, listenPort);
|
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, listenPort);
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
@ -562,7 +573,7 @@ int main(int argc, const char * argv[]) {
|
||||||
const char* PACKETS_PER_SECOND = "--packetsPerSecond";
|
const char* PACKETS_PER_SECOND = "--packetsPerSecond";
|
||||||
const char* packetsPerSecond = getCmdOption(argc, argv, PACKETS_PER_SECOND);
|
const char* packetsPerSecond = getCmdOption(argc, argv, PACKETS_PER_SECOND);
|
||||||
if (packetsPerSecond) {
|
if (packetsPerSecond) {
|
||||||
PACKETS_PER_CLIENT_PER_INTERVAL = atoi(packetsPerSecond)/10;
|
PACKETS_PER_CLIENT_PER_INTERVAL = atoi(packetsPerSecond)/INTERVALS_PER_SECOND;
|
||||||
if (PACKETS_PER_CLIENT_PER_INTERVAL < 1) {
|
if (PACKETS_PER_CLIENT_PER_INTERVAL < 1) {
|
||||||
PACKETS_PER_CLIENT_PER_INTERVAL = 1;
|
PACKETS_PER_CLIENT_PER_INTERVAL = 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue