Merge pull request #636 from PhilipRosedale/master

Touchlook tuned and always on!
This commit is contained in:
Andrzej Kapolka 2013-07-10 16:36:10 -07:00
commit 100f7c19c3
6 changed files with 67 additions and 62 deletions

View file

@ -341,6 +341,7 @@ void Application::initializeGL() {
QTimer* idleTimer = new QTimer(this);
connect(idleTimer, SIGNAL(timeout()), SLOT(idle()));
idleTimer->start(0);
_idleLoopStdev.reset();
if (_justStarted) {
float startupTime = (usecTimestampNow() - usecTimestamp(&_applicationStartupTime)) / 1000000.0;
@ -878,6 +879,8 @@ void Application::touchUpdateEvent(QTouchEvent* event) {
void Application::touchBeginEvent(QTouchEvent* event) {
touchUpdateEvent(event);
_lastTouchAvgX = _touchAvgX;
_lastTouchAvgY = _touchAvgY;
}
void Application::touchEndEvent(QTouchEvent* event) {
@ -961,28 +964,36 @@ static glm::vec3 getFaceVector(BoxFace face) {
}
void Application::idle() {
timeval check;
gettimeofday(&check, NULL);
// Only run simulation code if more than IDLE_SIMULATE_MSECS have passed since last time we ran
if (diffclock(&_lastTimeIdle, &check) > IDLE_SIMULATE_MSECS) {
double timeSinceLastUpdate = diffclock(&_lastTimeUpdated, &check);
if (timeSinceLastUpdate > IDLE_SIMULATE_MSECS) {
// If we're using multi-touch look, immediately process any
// touch events, and no other events.
// This is necessary because id the idle() call takes longer than the
// interval between idle() calls, the event loop never gets to run,
// and touch events get delayed.
if (_touchLook->isChecked()) {
sendPostedEvents(NULL, QEvent::TouchBegin);
sendPostedEvents(NULL, QEvent::TouchUpdate);
sendPostedEvents(NULL, QEvent::TouchEnd);
}
update(1.0f / _fps);
sendPostedEvents(NULL, QEvent::TouchBegin);
sendPostedEvents(NULL, QEvent::TouchUpdate);
sendPostedEvents(NULL, QEvent::TouchEnd);
const float BIGGEST_DELTA_TIME_SECS = 0.25f;
update(glm::clamp((float)timeSinceLastUpdate / 1000.f, 0.f, BIGGEST_DELTA_TIME_SECS));
_glWidget->updateGL();
_lastTimeIdle = check;
_lastTimeUpdated = check;
_idleLoopStdev.addValue(timeSinceLastUpdate);
// Record standard deviation and reset counter if needed
const int STDEV_SAMPLES = 500;
if (_idleLoopStdev.getSamples() > STDEV_SAMPLES) {
_idleLoopMeasuredJitter = _idleLoopStdev.getStDev();
_idleLoopStdev.reset();
}
}
}
void Application::terminate() {
@ -1496,10 +1507,6 @@ void Application::initMenu() {
optionsMenu->addAction("Noise", this, SLOT(setNoise(bool)), Qt::Key_N)->setCheckable(true);
(_gyroLook = optionsMenu->addAction("Smooth Gyro Look"))->setCheckable(true);
_gyroLook->setChecked(true);
(_mouseLook = optionsMenu->addAction("Mouse Look"))->setCheckable(true);
_mouseLook->setChecked(true);
(_touchLook = optionsMenu->addAction("Touch Look"))->setCheckable(true);
_touchLook->setChecked(false);
(_showHeadMouse = optionsMenu->addAction("Head Mouse"))->setCheckable(true);
_showHeadMouse->setChecked(false);
(_transmitterDrives = optionsMenu->addAction("Transmitter Drive"))->setCheckable(true);
@ -1700,7 +1707,7 @@ void Application::init() {
LeapManager::initialize();
gettimeofday(&_timerStart, NULL);
gettimeofday(&_lastTimeIdle, NULL);
gettimeofday(&_lastTimeUpdated, NULL);
loadSettings();
if (!shouldDynamicallySetJitterBuffer()) {
@ -1847,20 +1854,19 @@ void Application::update(float deltaTime) {
if (_myAvatar.getMode() == AVATAR_MODE_WALKING) {
_handControl.stop();
}
// Update from Mouse
if (_mouseLook->isChecked()) {
QPoint mouse = QCursor::pos();
_myAvatar.updateFromMouse(_glWidget->mapFromGlobal(mouse).x(),
_glWidget->mapFromGlobal(mouse).y(),
_glWidget->width(),
_glWidget->height());
}
// Update from Touch
if (_isTouchPressed && _touchLook->isChecked()) {
_myAvatar.updateFromTouch(_touchAvgX - _touchDragStartedAvgX,
_touchAvgY - _touchDragStartedAvgY);
if (_isTouchPressed) {
float TOUCH_YAW_SCALE = -50.0f;
float TOUCH_PITCH_SCALE = -50.0f;
_myAvatar.getHead().addYaw((_touchAvgX - _lastTouchAvgX)
* TOUCH_YAW_SCALE
* deltaTime);
_myAvatar.getHead().addPitch((_touchAvgY - _lastTouchAvgY)
* TOUCH_PITCH_SCALE
* deltaTime);
_lastTouchAvgX = _touchAvgX;
_lastTouchAvgY = _touchAvgY;
}
// Leap finger-sensing device

View file

@ -215,8 +215,6 @@ private:
QAction* _shouldLowPassFilter; // Use test lowpass filter
QAction* _gyroLook; // Whether to allow the gyro data from head to move your view
QAction* _renderAvatarBalls; // Switch between voxels and joints/balls for avatar render
QAction* _mouseLook; // Whether the have the mouse near edge of screen move your view
QAction* _touchLook; // Whether a 2-finger touch may be used to control look direction
QAction* _showHeadMouse; // Whether the have the mouse near edge of screen move your view
QAction* _transmitterDrives; // Whether to have Transmitter data move/steer the Avatar
QAction* _gravityUse; // Whether gravity is on or not
@ -264,7 +262,7 @@ private:
float _fps;
timeval _applicationStartupTime;
timeval _timerStart, _timerEnd;
timeval _lastTimeIdle;
timeval _lastTimeUpdated;
bool _justStarted;
Stars _stars;
@ -316,6 +314,8 @@ private:
float _touchAvgX;
float _touchAvgY;
float _lastTouchAvgX;
float _lastTouchAvgY;
float _touchDragStartedAvgX;
float _touchDragStartedAvgY;
bool _isTouchPressed; // true if multitouch has been pressed (clear when finished)
@ -364,6 +364,9 @@ private:
int _packetsPerSecond;
int _bytesPerSecond;
int _bytesCount;
StDev _idleLoopStdev;
float _idleLoopMeasuredJitter;
ToolsPalette _palette;
Swatch _swatch;

View file

@ -350,34 +350,7 @@ glm::vec3 Avatar::getUprightHeadPosition() const {
return _position + getWorldAlignedOrientation() * glm::vec3(0.0f, _pelvisToHeadLength, 0.0f);
}
void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight) {
// Update head yaw and pitch based on mouse input
const float MOUSE_ROTATE_SPEED = 0.01f;
const float MOUSE_PITCH_SPEED = 0.02f;
const int TITLE_BAR_HEIGHT = 46;
if ((mouseX > 1) && (mouseX < screenWidth) && (mouseY > TITLE_BAR_HEIGHT) && (mouseY < screenHeight)) {
//
// Mouse must be inside screen (not at edge) and not on title bar for movement to happen
//
int pixelMoveThreshold = screenWidth / 6;
glm::vec2 mouseVector(mouseX - (screenWidth / 2), mouseY - (screenHeight / 2));
if (glm::length(mouseVector) > pixelMoveThreshold) {
mouseVector -= glm::normalize(mouseVector) * (float) pixelMoveThreshold;
_head.addYaw(-mouseVector.x * MOUSE_ROTATE_SPEED);
_head.addPitch(-mouseVector.y * MOUSE_PITCH_SPEED);
}
}
}
void Avatar::updateFromTouch(float touchAvgDistX, float touchAvgDistY) {
const float TOUCH_ROTATE_SPEED = 0.01f;
const float TOUCH_PITCH_SPEED = 0.02f;
_head.addYaw(-touchAvgDistX * TOUCH_ROTATE_SPEED);
_head.addPitch(-touchAvgDistY * TOUCH_PITCH_SPEED);
}
void Avatar::updateThrust(float deltaTime, Transmitter * transmitter) {
//

View file

@ -88,8 +88,6 @@ public:
void simulate(float deltaTime, Transmitter* transmitter);
void updateThrust(float deltaTime, Transmitter * transmitter);
void updateFromGyrosAndOrWebcam(bool gyroLook, const glm::vec3& amplifyAngles);
void updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight);
void updateFromTouch(float touchAvgDistX, float touchAvgDistY);
void addBodyYaw(float y) {_bodyYaw += y;};
void render(bool lookingInMirror, bool renderAvatarBalls);

View file

@ -500,6 +500,20 @@ void runTimingTests() {
elapsedMsecs = diffclock(&startTime, &endTime);
printLog("powf(f, 0.5) usecs: %f\n", 1000.0f * elapsedMsecs / (float) numTests);
// Vec3 test
glm::vec3 vecA(randVector()), vecB(randVector());
float result;
gettimeofday(&startTime, NULL);
for (int i = 1; i < numTests; i++) {
glm::vec3 temp = vecA-vecB;
result = glm::dot(temp,temp);
}
gettimeofday(&endTime, NULL);
elapsedMsecs = diffclock(&startTime, &endTime);
printLog("vec3 assign and dot() usecs: %f\n", 1000.0f * elapsedMsecs / (float) numTests);
}
float loadSetting(QSettings* settings, const char* name, float defaultValue) {

View file

@ -6,8 +6,9 @@
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
//
#include "StdDev.h"
#include <limits>
#include <cmath>
#include "StdDev.h"
const int MAX_STDEV_SAMPLES = 1000;
@ -34,6 +35,16 @@ float StDev::getAverage() {
return average/(float)sampleCount;
else return 0;
}
/*
float StDev::getMax() {
float average = -FLT_MAX;
for (int i = 0; i < sampleCount; i++) {
average += data[i];
}
if (sampleCount > 0)
return average/(float)sampleCount;
else return 0;
}*/
float StDev::getStDev() {
float average = getAverage();