Moving headMouse, transmitter, and touchYaw/Pitch stuff into MyAvatar.

This commit is contained in:
Andrew Meadows 2014-01-31 17:42:48 -08:00
parent a7ffb7df1d
commit ed93d8db39
11 changed files with 240 additions and 229 deletions

View file

@ -132,8 +132,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_touchAvgX(0.0f),
_touchAvgY(0.0f),
_isTouchPressed(false),
_yawFromTouch(0.0f),
_pitchFromTouch(0.0f),
_mousePressed(false),
_isHoverVoxel(false),
_isHoverVoxelSounding(false),
@ -1821,9 +1819,9 @@ void Application::init() {
_voxelShader.init();
_pointShader.init();
_headMouseX = _mouseX = _glWidget->width() / 2;
_headMouseY = _mouseY = _glWidget->height() / 2;
QCursor::setPos(_headMouseX, _headMouseY);
_mouseX = _glWidget->width() / 2;
_mouseY = _glWidget->height() / 2;
QCursor::setPos(_mouseX, _mouseY);
// TODO: move _myAvatar out of Application. Move relevant code to MyAvataar or AvatarManager
_avatarManager.init();
@ -2164,11 +2162,6 @@ void Application::updateHandAndTouch(float deltaTime) {
// Update from Touch
if (_isTouchPressed) {
float TOUCH_YAW_SCALE = -0.25f;
float TOUCH_PITCH_SCALE = -12.5f;
float FIXED_TOUCH_TIMESTEP = 0.016f;
_yawFromTouch += ((_touchAvgX - _lastTouchAvgX) * TOUCH_YAW_SCALE * FIXED_TOUCH_TIMESTEP);
_pitchFromTouch += ((_touchAvgY - _lastTouchAvgY) * TOUCH_PITCH_SCALE * FIXED_TOUCH_TIMESTEP);
_lastTouchAvgX = _touchAvgX;
_lastTouchAvgY = _touchAvgY;
}
@ -2207,24 +2200,6 @@ void Application::updateThreads(float deltaTime) {
}
}
void Application::updateMyAvatarSimulation(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateMyAvatarSimulation()");
if (Menu::getInstance()->isOptionChecked(MenuOption::Gravity)) {
_myAvatar->setGravity(_environment.getGravity(_myAvatar->getPosition()));
}
else {
_myAvatar->setGravity(glm::vec3(0.0f, 0.0f, 0.0f));
}
if (Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _myTransmitter.isConnected()) {
_myAvatar->simulate(deltaTime, &_myTransmitter);
} else {
_myAvatar->simulate(deltaTime, NULL);
}
}
void Application::updateParticles(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateParticles()");
@ -2243,32 +2218,6 @@ void Application::updateMetavoxels(float deltaTime) {
}
}
void Application::updateTransmitter(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateTransmitter()");
// no transmitter drive implies transmitter pick
if (!Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _myTransmitter.isConnected()) {
_transmitterPickStart = _myAvatar->getChestPosition();
glm::vec3 direction = _myAvatar->getOrientation() *
glm::quat(glm::radians(_myTransmitter.getEstimatedRotation())) * IDENTITY_FRONT;
// check against voxels, avatars
const float MAX_PICK_DISTANCE = 100.0f;
float minDistance = MAX_PICK_DISTANCE;
VoxelDetail detail;
float distance;
BoxFace face;
if (_voxels.findRayIntersection(_transmitterPickStart, direction, detail, distance, face)) {
minDistance = min(minDistance, distance);
}
_transmitterPickEnd = _transmitterPickStart + direction * minDistance;
} else {
_transmitterPickStart = _transmitterPickEnd = glm::vec3();
}
}
void Application::updateCamera(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateCamera()");
@ -2376,13 +2325,11 @@ void Application::update(float deltaTime) {
updateLeap(deltaTime); // Leap finger-sensing device
updateSixense(deltaTime); // Razer Hydra controllers
updateSerialDevices(deltaTime); // Read serial port interface devices
updateAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
updateMyAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
_avatarManager.updateAvatars(deltaTime); //loop through all the other avatars and simulate them...
updateMyAvatarSimulation(deltaTime); // Simulate myself
_avatarManager.updateOtherAvatars(deltaTime); //loop through all the other avatars and simulate them...
updateParticles(deltaTime); // Simulate particle cloud movements
updateMetavoxels(deltaTime); // update metavoxels
updateTransmitter(deltaTime); // transmitter drive or pick
updateCamera(deltaTime); // handle various camera tweaks like off axis projection
updateDialogs(deltaTime); // update various stats dialogs if present
updateAudio(deltaTime); // Update audio stats for procedural sounds
@ -2392,54 +2339,17 @@ void Application::update(float deltaTime) {
_particleCollisionSystem.update(); // collide the particles...
}
void Application::updateAvatar(float deltaTime) {
void Application::updateMyAvatar(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateAvatar()");
PerformanceWarning warn(showWarnings, "Application::updateMyAvatar()");
// rotate body yaw for yaw received from multitouch
_myAvatar->setOrientation(_myAvatar->getOrientation()
* glm::quat(glm::vec3(0, _yawFromTouch, 0)));
_yawFromTouch = 0.f;
// apply pitch from touch
_myAvatar->getHead().setPitch(_myAvatar->getHead().getPitch() + _pitchFromTouch);
_pitchFromTouch = 0.0f;
// Update my avatar's state from gyros
_myAvatar->updateFromGyros(Menu::getInstance()->isOptionChecked(MenuOption::TurnWithHead));
// Update head mouse from faceshift if active
if (_faceshift.isActive()) {
glm::vec3 headVelocity = _faceshift.getHeadAngularVelocity();
// sets how quickly head angular rotation moves the head mouse
const float HEADMOUSE_FACESHIFT_YAW_SCALE = 40.f;
const float HEADMOUSE_FACESHIFT_PITCH_SCALE = 30.f;
_headMouseX -= headVelocity.y * HEADMOUSE_FACESHIFT_YAW_SCALE;
_headMouseY -= headVelocity.x * HEADMOUSE_FACESHIFT_PITCH_SCALE;
}
// Constrain head-driven mouse to edges of screen
_headMouseX = glm::clamp(_headMouseX, 0, _glWidget->width());
_headMouseY = glm::clamp(_headMouseY, 0, _glWidget->height());
if (OculusManager::isConnected()) {
float yaw, pitch, roll;
OculusManager::getEulerAngles(yaw, pitch, roll);
_myAvatar->getHead().setYaw(yaw);
_myAvatar->getHead().setPitch(pitch);
_myAvatar->getHead().setRoll(roll);
}
// Get audio loudness data from audio input device
_myAvatar->getHead().setAudioLoudness(_audio.getLastInputLoudness());
_myAvatar->update(deltaTime);
// send head/hand data to the avatar mixer and voxel server
QByteArray avatarData = byteArrayWithPopluatedHeader(PacketTypeAvatarData);
avatarData.append(_myAvatar->toByteArray());
QByteArray packet = byteArrayWithPopluatedHeader(PacketTypeAvatarData);
packet.append(_myAvatar->toByteArray());
controlledBroadcastToNodes(avatarData, NodeSet() << NodeType::AvatarMixer);
controlledBroadcastToNodes(packet, NodeSet() << NodeType::AvatarMixer);
// Update _viewFrustum with latest camera and view frustum data...
// NOTE: we get this from the view frustum, to make it simpler, since the
@ -2991,29 +2901,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
}
// render transmitter pick ray, if non-empty
if (_transmitterPickStart != _transmitterPickEnd) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::displaySide() ... transmitter pick ray...");
_myAvatar->renderTransmitterPickRay();
Glower glower;
const float TRANSMITTER_PICK_COLOR[] = { 1.0f, 1.0f, 0.0f };
glColor3fv(TRANSMITTER_PICK_COLOR);
glLineWidth(3.0f);
glBegin(GL_LINES);
glVertex3f(_transmitterPickStart.x, _transmitterPickStart.y, _transmitterPickStart.z);
glVertex3f(_transmitterPickEnd.x, _transmitterPickEnd.y, _transmitterPickEnd.z);
glEnd();
glLineWidth(1.0f);
glPushMatrix();
glTranslatef(_transmitterPickEnd.x, _transmitterPickEnd.y, _transmitterPickEnd.z);
const float PICK_END_RADIUS = 0.025f;
glutSolidSphere(PICK_END_RADIUS, 8, 8);
glPopMatrix();
}
// give external parties a change to hook in
emit renderingInWorldInterface();
}
@ -3037,71 +2926,38 @@ void Application::displayOverlay() {
// Render 2D overlay: I/O level bar graphs and text
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, _glWidget->width(), _glWidget->height(), 0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
// Display a single screen-size quad to create an alpha blended 'collision' flash
if (_audio.getCollisionFlashesScreen()) {
float collisionSoundMagnitude = _audio.getCollisionSoundMagnitude();
const float VISIBLE_COLLISION_SOUND_MAGNITUDE = 0.5f;
if (collisionSoundMagnitude > VISIBLE_COLLISION_SOUND_MAGNITUDE) {
renderCollisionOverlay(_glWidget->width(), _glWidget->height(), _audio.getCollisionSoundMagnitude());
}
glLoadIdentity();
gluOrtho2D(0, _glWidget->width(), _glWidget->height(), 0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
// Display a single screen-size quad to create an alpha blended 'collision' flash
if (_audio.getCollisionFlashesScreen()) {
float collisionSoundMagnitude = _audio.getCollisionSoundMagnitude();
const float VISIBLE_COLLISION_SOUND_MAGNITUDE = 0.5f;
if (collisionSoundMagnitude > VISIBLE_COLLISION_SOUND_MAGNITUDE) {
renderCollisionOverlay(_glWidget->width(), _glWidget->height(), _audio.getCollisionSoundMagnitude());
}
}
if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
displayStatsBackground(0x33333399, 0, _glWidget->height() - 68, 296, 68);
_audio.render(_glWidget->width(), _glWidget->height());
if (Menu::getInstance()->isOptionChecked(MenuOption::Oscilloscope)) {
int oscilloscopeTop = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) ? 130 : 25;
_audioScope.render(25, oscilloscopeTop);
}
if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
displayStatsBackground(0x33333399, 0, _glWidget->height() - 68, 296, 68);
_audio.render(_glWidget->width(), _glWidget->height());
if (Menu::getInstance()->isOptionChecked(MenuOption::Oscilloscope)) {
int oscilloscopeTop = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) ? 130 : 25;
_audioScope.render(25, oscilloscopeTop);
}
}
//noiseTest(_glWidget->width(), _glWidget->height());
//noiseTest(_glWidget->width(), _glWidget->height());
if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) {
// Display small target box at center or head mouse target that can also be used to measure LOD
glColor3f(1.0, 1.0, 1.0);
glDisable(GL_LINE_SMOOTH);
const int PIXEL_BOX = 16;
glBegin(GL_LINES);
glVertex2f(_headMouseX - PIXEL_BOX/2, _headMouseY);
glVertex2f(_headMouseX + PIXEL_BOX/2, _headMouseY);
glVertex2f(_headMouseX, _headMouseY - PIXEL_BOX/2);
glVertex2f(_headMouseX, _headMouseY + PIXEL_BOX/2);
glEnd();
glEnable(GL_LINE_SMOOTH);
glColor3f(1.f, 0.f, 0.f);
glPointSize(3.0f);
glDisable(GL_POINT_SMOOTH);
glBegin(GL_POINTS);
glVertex2f(_headMouseX - 1, _headMouseY + 1);
glEnd();
// If Faceshift is active, show eye pitch and yaw as separate pointer
if (_faceshift.isActive()) {
const float EYE_TARGET_PIXELS_PER_DEGREE = 40.0;
int eyeTargetX = (_glWidget->width() / 2) - _faceshift.getEstimatedEyeYaw() * EYE_TARGET_PIXELS_PER_DEGREE;
int eyeTargetY = (_glWidget->height() / 2) - _faceshift.getEstimatedEyePitch() * EYE_TARGET_PIXELS_PER_DEGREE;
glColor3f(0.0, 1.0, 1.0);
glDisable(GL_LINE_SMOOTH);
glBegin(GL_LINES);
glVertex2f(eyeTargetX - PIXEL_BOX/2, eyeTargetY);
glVertex2f(eyeTargetX + PIXEL_BOX/2, eyeTargetY);
glVertex2f(eyeTargetX, eyeTargetY - PIXEL_BOX/2);
glVertex2f(eyeTargetX, eyeTargetY + PIXEL_BOX/2);
glEnd();
}
_myAvatar->renderHeadMouse();
}
// Show hand transmitter data if detected
if (_myTransmitter.isConnected()) {
_myTransmitter.renderLevels(_glWidget->width(), _glWidget->height());
}
_myAvatar->renderTransmitterLevels(_glWidget->width(), _glWidget->height());
// Display stats and log text onscreen
glLineWidth(1.0f);
glPointSize(1.0f);
@ -3951,8 +3807,8 @@ void Application::eyedropperVoxelUnderCursor() {
}
void Application::resetSensors() {
_headMouseX = _mouseX = _glWidget->width() / 2;
_headMouseY = _mouseY = _glWidget->height() / 2;
_mouseX = _glWidget->width() / 2;
_mouseY = _glWidget->height() / 2;
_faceshift.reset();
@ -3960,11 +3816,8 @@ void Application::resetSensors() {
OculusManager::reset();
}
QCursor::setPos(_headMouseX, _headMouseY);
QCursor::setPos(_mouseX, _mouseY);
_myAvatar->reset();
_myTransmitter.resetLevels();
_myAvatar->setVelocity(glm::vec3(0,0,0));
_myAvatar->setThrust(glm::vec3(0,0,0));
QMetaObject::invokeMethod(&_audio, "reset", Qt::QueuedConnection);
}
@ -4093,7 +3946,7 @@ void Application::nodeKilled(SharedNodePointer node) {
} else if (node->getType() == NodeType::AvatarMixer) {
// our avatar mixer has gone away - clear the hash of avatars
_avatarManager.clearMixedAvatars();
_avatarManager.clearOtherAvatars();
}
}
@ -4291,7 +4144,7 @@ void Application::toggleLogDialog() {
}
void Application::initAvatarAndViewFrustum() {
updateAvatar(0.f);
updateMyAvatar(0.f);
}
QString Application::getLocalVoxelCacheFileName() {

View file

@ -282,10 +282,8 @@ private:
void updateSixense(float deltaTime);
void updateSerialDevices(float deltaTime);
void updateThreads(float deltaTime);
void updateMyAvatarSimulation(float deltaTime);
void updateParticles(float deltaTime);
void updateMetavoxels(float deltaTime);
void updateTransmitter(float deltaTime);
void updateCamera(float deltaTime);
void updateDialogs(float deltaTime);
void updateAudio(float deltaTime);
@ -297,7 +295,7 @@ private:
void renderLookatIndicator(glm::vec3 pointOfInterest);
void renderHighlightVoxel(VoxelDetail voxel);
void updateAvatar(float deltaTime);
void updateMyAvatar(float deltaTime);
void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
@ -377,8 +375,6 @@ private:
MyAvatar* _myAvatar; // TODO: move this and relevant code to AvatarManager (or MyAvatar as the case may be)
Profile _profile; // The data-server linked profile for this user
Transmitter _myTransmitter; // Gets UDP data from transmitter app used to animate the avatar
Faceshift _faceshift;
SixenseManager _sixenseManager;
@ -397,8 +393,6 @@ private:
Environment _environment;
int _headMouseX, _headMouseY;
int _mouseX;
int _mouseY;
int _mouseDragStartedX;
@ -417,8 +411,6 @@ private:
float _touchDragStartedAvgX;
float _touchDragStartedAvgY;
bool _isTouchPressed; // true if multitouch has been pressed (clear when finished)
float _yawFromTouch;
float _pitchFromTouch;
VoxelDetail _mouseVoxelDragging;
bool _mousePressed; // true if mouse has been pressed (clear when finished)
@ -443,9 +435,6 @@ private:
bool _lookingAwayFromOrigin;
glm::vec3 _nudgeGuidePosition;
glm::vec3 _transmitterPickStart;
glm::vec3 _transmitterPickEnd;
ChatEntry _chatEntry; // chat entry field
bool _chatEntryOn; // Whether to show the chat entry

View file

@ -45,7 +45,7 @@ void DatagramProcessor::processDatagrams() {
switch (packetTypeForPacket(incomingPacket)) {
case PacketTypeTransmitterData:
// V2 = IOS transmitter app
application->_myTransmitter.processIncomingData(reinterpret_cast<unsigned char*>(incomingPacket.data()),
application->getAvatar()->getTransmitter().processIncomingData(reinterpret_cast<unsigned char*>(incomingPacket.data()),
incomingPacket.size());
break;

View file

@ -106,7 +106,7 @@ glm::quat Avatar::getWorldAlignedOrientation () const {
return computeRotationFromBodyToWorldUp() * getOrientation();
}
void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
void Avatar::simulate(float deltaTime) {
if (_scale != _targetScale) {
setScale(_targetScale);
}

View file

@ -20,7 +20,6 @@
#include "InterfaceConfig.h"
#include "SkeletonModel.h"
#include "world.h"
#include "devices/Transmitter.h"
static const float SCALING_RATIO = .05f;
static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1
@ -73,7 +72,7 @@ public:
~Avatar();
void init();
void simulate(float deltaTime, Transmitter* transmitter);
void simulate(float deltaTime);
void render(bool forceRenderHead);
//setters

View file

@ -33,10 +33,10 @@ void AvatarManager::init() {
_avatarHash.insert(MY_AVATAR_KEY, _myAvatar);
}
void AvatarManager::updateAvatars(float deltaTime) {
void AvatarManager::updateOtherAvatars(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateAvatars()");
Application* applicationInstance = Application::getInstance();
glm::vec3 mouseOrigin = applicationInstance->getMouseRayOrigin();
glm::vec3 mouseDirection = applicationInstance->getMouseRayDirection();
@ -46,14 +46,14 @@ void AvatarManager::updateAvatars(float deltaTime) {
while (avatarIterator != _avatarHash.end()) {
Avatar* avatar = static_cast<Avatar*>(avatarIterator.value().data());
if (avatar == static_cast<Avatar*>(_myAvatar.data())) {
// for now skip updates to _myAvatar because it is done explicitly in Application
// TODO: update _myAvatar in this context
// DO NOT update _myAvatar! Its update has already been done earlier in the main loop.
//updateMyAvatar(deltaTime);
++avatarIterator;
continue;
}
if (avatar->getOwningAvatarMixer()) {
// this avatar's mixer is still around, go ahead and simulate it
avatar->simulate(deltaTime, NULL);
avatar->simulate(deltaTime);
avatar->setMouseRay(mouseOrigin, mouseDirection);
++avatarIterator;
} else {
@ -108,7 +108,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
if (avatar->getTargetScale() < MIN_FADE_SCALE) {
fadingIterator = _avatarFades.erase(fadingIterator);
} else {
avatar->simulate(deltaTime, NULL);
avatar->simulate(deltaTime);
++fadingIterator;
}
}
@ -224,7 +224,7 @@ AvatarHash::iterator AvatarManager::erase(const AvatarHash::iterator& iterator)
}
}
void AvatarManager::clearMixedAvatars() {
void AvatarManager::clearOtherAvatars() {
// clear any avatars that came from an avatar-mixer
AvatarHash::iterator removeAvatar = _avatarHash.begin();
while (removeAvatar != _avatarHash.end()) {

View file

@ -29,10 +29,10 @@ public:
MyAvatar* getMyAvatar() { return _myAvatar.data(); }
void updateAvatars(float deltaTime);
void updateOtherAvatars(float deltaTime);
void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false);
void clearMixedAvatars();
void clearOtherAvatars();
public slots:
void processDataServerResponse(const QString& userString, const QStringList& keyList, const QStringList& valueList);

View file

@ -16,10 +16,14 @@
#include <SharedUtil.h>
#include "Application.h"
#include "Audio.h"
#include "DataServerClient.h"
#include "Environment.h"
#include "Menu.h"
#include "MyAvatar.h"
#include "Physics.h"
#include "VoxelSystem.h"
#include "devices/Faceshift.h"
#include "devices/OculusManager.h"
#include "ui/TextRenderer.h"
@ -66,8 +70,15 @@ MyAvatar::~MyAvatar() {
}
void MyAvatar::reset() {
// TODO? resurrect headMouse stuff?
//_headMouseX = _glWidget->width() / 2;
//_headMouseY = _glWidget->height() / 2;
_head.reset();
_hand.reset();
setVelocity(glm::vec3(0,0,0));
setThrust(glm::vec3(0,0,0));
_transmitter.resetLevels();
}
void MyAvatar::setMoveTarget(const glm::vec3 moveTarget) {
@ -75,7 +86,89 @@ void MyAvatar::setMoveTarget(const glm::vec3 moveTarget) {
_moveTargetStepCounter = 0;
}
void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
void MyAvatar::updateTransmitter(float deltaTime) {
// no transmitter drive implies transmitter pick
if (!Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _transmitter.isConnected()) {
_transmitterPickStart = getChestPosition();
glm::vec3 direction = getOrientation() * glm::quat(glm::radians(_transmitter.getEstimatedRotation())) * IDENTITY_FRONT;
// check against voxels, avatars
const float MAX_PICK_DISTANCE = 100.0f;
float minDistance = MAX_PICK_DISTANCE;
VoxelDetail detail;
float distance;
BoxFace face;
VoxelSystem* voxels = Application::getInstance()->getVoxels();
if (voxels->findRayIntersection(_transmitterPickStart, direction, detail, distance, face)) {
minDistance = min(minDistance, distance);
}
_transmitterPickEnd = _transmitterPickStart + direction * minDistance;
} else {
_transmitterPickStart = _transmitterPickEnd = glm::vec3();
}
}
void MyAvatar::update(float deltaTime) {
updateTransmitter(deltaTime);
// TODO: resurrect touch interactions between avatars
//// rotate body yaw for yaw received from multitouch
//setOrientation(getOrientation() * glm::quat(glm::vec3(0, _yawFromTouch, 0)));
//_yawFromTouch = 0.f;
//
//// apply pitch from touch
//_head.setPitch(_head.getPitch() + _pitchFromTouch);
//_pitchFromTouch = 0.0f;
//
//float TOUCH_YAW_SCALE = -0.25f;
//float TOUCH_PITCH_SCALE = -12.5f;
//float FIXED_TOUCH_TIMESTEP = 0.016f;
//_yawFromTouch += ((_touchAvgX - _lastTouchAvgX) * TOUCH_YAW_SCALE * FIXED_TOUCH_TIMESTEP);
//_pitchFromTouch += ((_touchAvgY - _lastTouchAvgY) * TOUCH_PITCH_SCALE * FIXED_TOUCH_TIMESTEP);
// Update my avatar's state from gyros
updateFromGyros(Menu::getInstance()->isOptionChecked(MenuOption::TurnWithHead));
// Update head mouse from faceshift if active
Faceshift* faceshift = Application::getInstance()->getFaceshift();
if (faceshift->isActive()) {
glm::vec3 headVelocity = faceshift->getHeadAngularVelocity();
// TODO? resurrect headMouse stuff?
//// sets how quickly head angular rotation moves the head mouse
//const float HEADMOUSE_FACESHIFT_YAW_SCALE = 40.f;
//const float HEADMOUSE_FACESHIFT_PITCH_SCALE = 30.f;
//_headMouseX -= headVelocity.y * HEADMOUSE_FACESHIFT_YAW_SCALE;
//_headMouseY -= headVelocity.x * HEADMOUSE_FACESHIFT_PITCH_SCALE;
//
//// Constrain head-driven mouse to edges of screen
//_headMouseX = glm::clamp(_headMouseX, 0, _glWidget->width());
//_headMouseY = glm::clamp(_headMouseY, 0, _glWidget->height());
}
if (OculusManager::isConnected()) {
float yaw, pitch, roll;
OculusManager::getEulerAngles(yaw, pitch, roll);
_head.setYaw(yaw);
_head.setPitch(pitch);
_head.setRoll(roll);
}
// Get audio loudness data from audio input device
_head.setAudioLoudness(Application::getInstance()->getAudio()->getLastInputLoudness());
if (Menu::getInstance()->isOptionChecked(MenuOption::Gravity)) {
setGravity(Application::getInstance()->getEnvironment()->getGravity(getPosition()));
} else {
setGravity(glm::vec3(0.0f, 0.0f, 0.0f));
}
simulate(deltaTime);
}
void MyAvatar::simulate(float deltaTime) {
glm::quat orientation = getOrientation();
@ -97,7 +190,7 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
}
// Collect thrust forces from keyboard and devices
updateThrust(deltaTime, transmitter);
updateThrust(deltaTime);
// copy velocity so we can use it later for acceleration
glm::vec3 oldVelocity = getVelocity();
@ -430,6 +523,74 @@ void MyAvatar::render(bool forceRenderHead) {
}
}
void MyAvatar::renderHeadMouse() const {
// TODO? resurrect headMouse stuff?
/*
// Display small target box at center or head mouse target that can also be used to measure LOD
glColor3f(1.0, 1.0, 1.0);
glDisable(GL_LINE_SMOOTH);
const int PIXEL_BOX = 16;
glBegin(GL_LINES);
glVertex2f(_headMouseX - PIXEL_BOX/2, _headMouseY);
glVertex2f(_headMouseX + PIXEL_BOX/2, _headMouseY);
glVertex2f(_headMouseX, _headMouseY - PIXEL_BOX/2);
glVertex2f(_headMouseX, _headMouseY + PIXEL_BOX/2);
glEnd();
glEnable(GL_LINE_SMOOTH);
glColor3f(1.f, 0.f, 0.f);
glPointSize(3.0f);
glDisable(GL_POINT_SMOOTH);
glBegin(GL_POINTS);
glVertex2f(_headMouseX - 1, _headMouseY + 1);
glEnd();
// If Faceshift is active, show eye pitch and yaw as separate pointer
if (_faceshift.isActive()) {
const float EYE_TARGET_PIXELS_PER_DEGREE = 40.0;
int eyeTargetX = (_glWidget->width() / 2) - _faceshift.getEstimatedEyeYaw() * EYE_TARGET_PIXELS_PER_DEGREE;
int eyeTargetY = (_glWidget->height() / 2) - _faceshift.getEstimatedEyePitch() * EYE_TARGET_PIXELS_PER_DEGREE;
glColor3f(0.0, 1.0, 1.0);
glDisable(GL_LINE_SMOOTH);
glBegin(GL_LINES);
glVertex2f(eyeTargetX - PIXEL_BOX/2, eyeTargetY);
glVertex2f(eyeTargetX + PIXEL_BOX/2, eyeTargetY);
glVertex2f(eyeTargetX, eyeTargetY - PIXEL_BOX/2);
glVertex2f(eyeTargetX, eyeTargetY + PIXEL_BOX/2);
glEnd();
}
*/
}
void MyAvatar::renderTransmitterPickRay() const {
if (_transmitterPickStart != _transmitterPickEnd) {
Glower glower;
const float TRANSMITTER_PICK_COLOR[] = { 1.0f, 1.0f, 0.0f };
glColor3fv(TRANSMITTER_PICK_COLOR);
glLineWidth(3.0f);
glBegin(GL_LINES);
glVertex3f(_transmitterPickStart.x, _transmitterPickStart.y, _transmitterPickStart.z);
glVertex3f(_transmitterPickEnd.x, _transmitterPickEnd.y, _transmitterPickEnd.z);
glEnd();
glLineWidth(1.0f);
glPushMatrix();
glTranslatef(_transmitterPickEnd.x, _transmitterPickEnd.y, _transmitterPickEnd.z);
const float PICK_END_RADIUS = 0.025f;
glutSolidSphere(PICK_END_RADIUS, 8, 8);
glPopMatrix();
}
}
void MyAvatar::renderTransmitterLevels(int width, int height) const {
// Show hand transmitter data if detected
if (_transmitter.isConnected()) {
_transmitter.renderLevels(width, height);
}
}
void MyAvatar::saveData(QSettings* settings) {
settings->beginGroup("Avatar");
@ -547,7 +708,7 @@ void MyAvatar::renderBody(bool forceRenderHead) {
_hand.render(true);
}
void MyAvatar::updateThrust(float deltaTime, Transmitter * transmitter) {
void MyAvatar::updateThrust(float deltaTime) {
//
// Gather thrust information from keyboard and sensors to apply to avatar motion
//
@ -595,9 +756,9 @@ void MyAvatar::updateThrust(float deltaTime, Transmitter * transmitter) {
}
// Add thrusts from Transmitter
if (transmitter) {
transmitter->checkForLostTransmitter();
glm::vec3 rotation = transmitter->getEstimatedRotation();
if (Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _transmitter.isConnected()) {
_transmitter.checkForLostTransmitter();
glm::vec3 rotation = _transmitter.getEstimatedRotation();
const float TRANSMITTER_MIN_RATE = 1.f;
const float TRANSMITTER_MIN_YAW_RATE = 4.f;
const float TRANSMITTER_LATERAL_FORCE_SCALE = 5.f;
@ -615,9 +776,9 @@ void MyAvatar::updateThrust(float deltaTime, Transmitter * transmitter) {
if (fabs(rotation.y) > TRANSMITTER_MIN_YAW_RATE) {
_bodyYawDelta += rotation.y * TRANSMITTER_YAW_SCALE * deltaTime;
}
if (transmitter->getTouchState()->state == 'D') {
if (_transmitter.getTouchState()->state == 'D') {
_thrust += TRANSMITTER_UP_FORCE_SCALE *
(float)(transmitter->getTouchState()->y - TOUCH_POSITION_RANGE_HALF) / TOUCH_POSITION_RANGE_HALF *
(float)(_transmitter.getTouchState()->y - TOUCH_POSITION_RANGE_HALF) / TOUCH_POSITION_RANGE_HALF *
TRANSMITTER_LIFT_SCALE *
deltaTime *
up;

View file

@ -11,6 +11,8 @@
#include <QSettings>
#include <devices/Transmitter.h>
#include "Avatar.h"
enum AvatarHandState
@ -30,10 +32,16 @@ public:
~MyAvatar();
void reset();
void simulate(float deltaTime, Transmitter* transmitter);
void update(float deltaTime);
void simulate(float deltaTime);
void updateFromGyros(bool turnWithHead);
void updateTransmitter(float deltaTime);
void render(bool forceRenderHead);
void renderDebugBodyPoints();
void renderHeadMouse() const;
void renderTransmitterPickRay() const;
void renderTransmitterLevels(int width, int height) const;
// setters
void setMousePressed(bool mousePressed) { _mousePressed = mousePressed; }
@ -53,6 +61,7 @@ public:
float getAbsoluteHeadYaw() const;
const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; }
const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; }
Transmitter& getTransmitter() { return _transmitter; }
glm::vec3 getGravity() const { return _gravity; }
glm::vec3 getUprightHeadPosition() const;
@ -76,9 +85,7 @@ public:
void orbit(const glm::vec3& position, int deltaX, int deltaY);
AvatarData* getLookAtTargetAvatar() const { return _lookAtTargetAvatar.data(); }
void updateLookAtTargetAvatar(glm::vec3& eyePosition);
void clearLookAtTargetAvatar();
public slots:
@ -109,9 +116,13 @@ private:
int _moveTargetStepCounter;
QWeakPointer<AvatarData> _lookAtTargetAvatar;
Transmitter _transmitter; // Gets UDP data from transmitter app used to animate the avatar
glm::vec3 _transmitterPickStart;
glm::vec3 _transmitterPickEnd;
// private methods
void renderBody(bool forceRenderHead);
void updateThrust(float deltaTime, Transmitter * transmitter);
void updateThrust(float deltaTime);
void updateHandMovementAndTouching(float deltaTime);
void updateAvatarCollisions(float deltaTime);
void updateCollisionWithEnvironment(float deltaTime);

View file

@ -113,7 +113,7 @@ void Transmitter::processIncomingData(unsigned char* packetData, int numBytes) {
}
}
void Transmitter::renderLevels(int width, int height) {
void Transmitter::renderLevels(int width, int height) const {
char val[50];
const int LEVEL_CORNER_X = 10;
const int LEVEL_CORNER_Y = 400;
@ -163,7 +163,5 @@ void Transmitter::renderLevels(int width, int height) {
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y - 6);
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 30);
glEnd();
}

View file

@ -29,8 +29,8 @@ public:
void render();
void checkForLostTransmitter();
void resetLevels();
void renderLevels(int width, int height);
bool isConnected() { return _isConnected; };
void renderLevels(int width, int height) const;
bool isConnected() const { return _isConnected; };
const glm::vec3 getLastRotationRate() const { return _lastRotationRate; };
const glm::vec3 getLastAcceleration() const { return _lastRotationRate; };
const glm::vec3 getEstimatedRotation() const { return _estimatedRotation; };