use radians instead of degrees (almost) everywhere

This commit is contained in:
Andrew Meadows 2014-03-11 17:26:58 -07:00
parent de8165c544
commit aa8c2fc8cb
51 changed files with 302 additions and 306 deletions

View file

@ -5,6 +5,7 @@ if (WIN32)
endif (WIN32) endif (WIN32)
project(hifi) project(hifi)
add_definitions(-DGLM_FORCE_RADIANS)
if (WIN32) if (WIN32)
add_definitions(-DNOMINMAX -D_CRT_SECURE_NO_WARNINGS) add_definitions(-DNOMINMAX -D_CRT_SECURE_NO_WARNINGS)

View file

@ -78,9 +78,9 @@ glm::vec3 bugDirection = glm::vec3(0, 0, 1);
const int VOXELS_PER_BUG = 18; const int VOXELS_PER_BUG = 18;
glm::vec3 bugPathCenter = glm::vec3(0.25f,0.15f,0.25f); // glm::vec3(BUG_VOXEL_SIZE * 150.0, BUG_VOXEL_SIZE * 30.0, BUG_VOXEL_SIZE * 150.0); glm::vec3 bugPathCenter = glm::vec3(0.25f,0.15f,0.25f); // glm::vec3(BUG_VOXEL_SIZE * 150.0, BUG_VOXEL_SIZE * 30.0, BUG_VOXEL_SIZE * 150.0);
float bugPathRadius = 0.2f; //BUG_VOXEL_SIZE * 140.0; float bugPathRadius = 0.2f; //BUG_VOXEL_SIZE * 140.0;
float bugPathTheta = 0.0 * PI_OVER_180; float bugPathTheta = 0.0f * RADIANS_PER_DEGREE;
float bugRotation = 0.0 * PI_OVER_180; float bugRotation = 0.0f * RADIANS_PER_DEGREE;
float bugAngleDelta = 0.2 * PI_OVER_180; float bugAngleDelta = 0.2f * RADIANS_PER_DEGREE;
bool moveBugInLine = false; bool moveBugInLine = false;
class BugPart { class BugPart {
@ -160,11 +160,11 @@ static void renderMovingBug() {
bugPosition.z += (bugDirection.z * BUG_VOXEL_SIZE); bugPosition.z += (bugDirection.z * BUG_VOXEL_SIZE);
// Check boundaries // Check boundaries
if (bugPosition.z > 1.0) { if (bugPosition.z > 1.0f) {
bugDirection.z = -1; bugDirection.z = -1.f;
} }
if (bugPosition.z < BUG_VOXEL_SIZE) { if (bugPosition.z < BUG_VOXEL_SIZE) {
bugDirection.z = 1; bugDirection.z = 1.f;
} }
} else { } else {
@ -174,9 +174,9 @@ static void renderMovingBug() {
bugRotation -= bugAngleDelta; // rotate slightly bugRotation -= bugAngleDelta; // rotate slightly
// If we loop past end of circle, just reset back into normal range // If we loop past end of circle, just reset back into normal range
if (bugPathTheta > (360.0f * PI_OVER_180)) { if (bugPathTheta > TWO_PI) {
bugPathTheta = 0; bugPathTheta = 0.f;
bugRotation = 0; bugRotation = 0.f;
} }
float x = bugPathCenter.x + bugPathRadius * cos(bugPathTheta); float x = bugPathCenter.x + bugPathRadius * cos(bugPathTheta);
@ -225,7 +225,7 @@ static void sendVoxelBlinkMessage() {
VoxelDetail detail; VoxelDetail detail;
detail.s = BEACON_SIZE; detail.s = BEACON_SIZE;
glm::vec3 position = glm::vec3(0, 0, detail.s); glm::vec3 position = glm::vec3(0.f, 0.f, detail.s);
detail.x = detail.s * floor(position.x / detail.s); detail.x = detail.s * floor(position.x / detail.s);
detail.y = detail.s * floor(position.y / detail.s); detail.y = detail.s * floor(position.y / detail.s);

View file

@ -114,7 +114,7 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf
const float OFF_AXIS_ATTENUATION_FORMULA_STEP = (1 - MAX_OFF_AXIS_ATTENUATION) / 2.0f; const float OFF_AXIS_ATTENUATION_FORMULA_STEP = (1 - MAX_OFF_AXIS_ATTENUATION) / 2.0f;
float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION +
(OFF_AXIS_ATTENUATION_FORMULA_STEP * (angleOfDelivery / 90.0f)); (OFF_AXIS_ATTENUATION_FORMULA_STEP * (angleOfDelivery / PI_OVER_TWO));
// multiply the current attenuation coefficient by the calculated off axis coefficient // multiply the current attenuation coefficient by the calculated off axis coefficient
attenuationCoefficient *= offAxisCoefficient; attenuationCoefficient *= offAxisCoefficient;
@ -148,7 +148,7 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf
// figure out the number of samples of delay and the ratio of the amplitude // figure out the number of samples of delay and the ratio of the amplitude
// in the weak channel for audio spatialization // in the weak channel for audio spatialization
float sinRatio = fabsf(sinf(glm::radians(bearingRelativeAngleToSource))); float sinRatio = fabsf(sinf(bearingRelativeAngleToSource));
numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
} }

View file

@ -507,7 +507,7 @@ void Application::paintGL() {
float headHeight = _myAvatar->getHead()->calculateAverageEyePosition().y - _myAvatar->getPosition().y; float headHeight = _myAvatar->getHead()->calculateAverageEyePosition().y - _myAvatar->getPosition().y;
_myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _myAvatar->getScale()); _myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _myAvatar->getScale());
_myCamera.setTargetPosition(_myAvatar->getPosition() + glm::vec3(0, headHeight, 0)); _myCamera.setTargetPosition(_myAvatar->getPosition() + glm::vec3(0, headHeight, 0));
_myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PIf, 0.0f))); _myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f)));
} }
// Update camera position // Update camera position
@ -744,7 +744,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
if (!_myAvatar->getDriveKeys(UP)) { if (!_myAvatar->getDriveKeys(UP)) {
_myAvatar->jump(); _myAvatar->jump();
} }
_myAvatar->setDriveKeys(UP, 1); _myAvatar->setDriveKeys(UP, 1.f);
break; break;
case Qt::Key_Asterisk: case Qt::Key_Asterisk:
@ -752,11 +752,11 @@ void Application::keyPressEvent(QKeyEvent* event) {
break; break;
case Qt::Key_C: case Qt::Key_C:
_myAvatar->setDriveKeys(DOWN, 1); _myAvatar->setDriveKeys(DOWN, 1.f);
break; break;
case Qt::Key_W: case Qt::Key_W:
_myAvatar->setDriveKeys(FWD, 1); _myAvatar->setDriveKeys(FWD, 1.f);
break; break;
case Qt::Key_S: case Qt::Key_S:
@ -765,7 +765,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
} else if (!isShifted && isMeta) { } else if (!isShifted && isMeta) {
takeSnapshot(); takeSnapshot();
} else { } else {
_myAvatar->setDriveKeys(BACK, 1); _myAvatar->setDriveKeys(BACK, 1.f);
} }
break; break;
@ -783,12 +783,12 @@ void Application::keyPressEvent(QKeyEvent* event) {
if (isShifted) { if (isShifted) {
Menu::getInstance()->triggerOption(MenuOption::Atmosphere); Menu::getInstance()->triggerOption(MenuOption::Atmosphere);
} else { } else {
_myAvatar->setDriveKeys(ROT_LEFT, 1); _myAvatar->setDriveKeys(ROT_LEFT, 1.f);
} }
break; break;
case Qt::Key_D: case Qt::Key_D:
_myAvatar->setDriveKeys(ROT_RIGHT, 1); _myAvatar->setDriveKeys(ROT_RIGHT, 1.f);
break; break;
case Qt::Key_Return: case Qt::Key_Return:
@ -800,19 +800,19 @@ void Application::keyPressEvent(QKeyEvent* event) {
break; break;
case Qt::Key_Up: case Qt::Key_Up:
_myAvatar->setDriveKeys(isShifted ? UP : FWD, 1); _myAvatar->setDriveKeys(isShifted ? UP : FWD, 1.f);
break; break;
case Qt::Key_Down: case Qt::Key_Down:
_myAvatar->setDriveKeys(isShifted ? DOWN : BACK, 1); _myAvatar->setDriveKeys(isShifted ? DOWN : BACK, 1.f);
break; break;
case Qt::Key_Left: case Qt::Key_Left:
_myAvatar->setDriveKeys(isShifted ? LEFT : ROT_LEFT, 1); _myAvatar->setDriveKeys(isShifted ? LEFT : ROT_LEFT, 1.f);
break; break;
case Qt::Key_Right: case Qt::Key_Right:
_myAvatar->setDriveKeys(isShifted ? RIGHT : ROT_RIGHT, 1); _myAvatar->setDriveKeys(isShifted ? RIGHT : ROT_RIGHT, 1.f);
break; break;
case Qt::Key_I: case Qt::Key_I:
@ -946,47 +946,47 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
switch (event->key()) { switch (event->key()) {
case Qt::Key_E: case Qt::Key_E:
_myAvatar->setDriveKeys(UP, 0); _myAvatar->setDriveKeys(UP, 0.f);
break; break;
case Qt::Key_C: case Qt::Key_C:
_myAvatar->setDriveKeys(DOWN, 0); _myAvatar->setDriveKeys(DOWN, 0.f);
break; break;
case Qt::Key_W: case Qt::Key_W:
_myAvatar->setDriveKeys(FWD, 0); _myAvatar->setDriveKeys(FWD, 0.f);
break; break;
case Qt::Key_S: case Qt::Key_S:
_myAvatar->setDriveKeys(BACK, 0); _myAvatar->setDriveKeys(BACK, 0.f);
break; break;
case Qt::Key_A: case Qt::Key_A:
_myAvatar->setDriveKeys(ROT_LEFT, 0); _myAvatar->setDriveKeys(ROT_LEFT, 0.f);
break; break;
case Qt::Key_D: case Qt::Key_D:
_myAvatar->setDriveKeys(ROT_RIGHT, 0); _myAvatar->setDriveKeys(ROT_RIGHT, 0.f);
break; break;
case Qt::Key_Up: case Qt::Key_Up:
_myAvatar->setDriveKeys(FWD, 0); _myAvatar->setDriveKeys(FWD, 0.f);
_myAvatar->setDriveKeys(UP, 0); _myAvatar->setDriveKeys(UP, 0.f);
break; break;
case Qt::Key_Down: case Qt::Key_Down:
_myAvatar->setDriveKeys(BACK, 0); _myAvatar->setDriveKeys(BACK, 0.f);
_myAvatar->setDriveKeys(DOWN, 0); _myAvatar->setDriveKeys(DOWN, 0.f);
break; break;
case Qt::Key_Left: case Qt::Key_Left:
_myAvatar->setDriveKeys(LEFT, 0); _myAvatar->setDriveKeys(LEFT, 0.f);
_myAvatar->setDriveKeys(ROT_LEFT, 0); _myAvatar->setDriveKeys(ROT_LEFT, 0.f);
break; break;
case Qt::Key_Right: case Qt::Key_Right:
_myAvatar->setDriveKeys(RIGHT, 0); _myAvatar->setDriveKeys(RIGHT, 0.f);
_myAvatar->setDriveKeys(ROT_RIGHT, 0); _myAvatar->setDriveKeys(ROT_RIGHT, 0.f);
break; break;
default: default:
@ -1488,7 +1488,7 @@ void Application::init() {
3.0f * TREE_SCALE / 2.0f)); 3.0f * TREE_SCALE / 2.0f));
_sharedVoxelSystemViewFrustum.setNearClip(TREE_SCALE / 2.0f); _sharedVoxelSystemViewFrustum.setNearClip(TREE_SCALE / 2.0f);
_sharedVoxelSystemViewFrustum.setFarClip(3.0f * TREE_SCALE / 2.0f); _sharedVoxelSystemViewFrustum.setFarClip(3.0f * TREE_SCALE / 2.0f);
_sharedVoxelSystemViewFrustum.setFieldOfView(90); _sharedVoxelSystemViewFrustum.setFieldOfView(90.f);
_sharedVoxelSystemViewFrustum.setOrientation(glm::quat()); _sharedVoxelSystemViewFrustum.setOrientation(glm::quat());
_sharedVoxelSystemViewFrustum.calculate(); _sharedVoxelSystemViewFrustum.calculate();
_sharedVoxelSystem.setViewFrustum(&_sharedVoxelSystemViewFrustum); _sharedVoxelSystem.setViewFrustum(&_sharedVoxelSystemViewFrustum);
@ -2120,7 +2120,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
// We will use these below, from either the camera or head vectors calculated above // We will use these below, from either the camera or head vectors calculated above
glm::vec3 position(camera.getPosition()); glm::vec3 position(camera.getPosition());
float fov = camera.getFieldOfView(); float fov = camera.getFieldOfView(); // degrees
float nearClip = camera.getNearClip(); float nearClip = camera.getNearClip();
float farClip = camera.getFarClip(); float farClip = camera.getFarClip();
float aspectRatio = camera.getAspectRatio(); float aspectRatio = camera.getAspectRatio();
@ -2133,7 +2133,7 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
// Also make sure it's got the correct lens details from the camera // Also make sure it's got the correct lens details from the camera
viewFrustum.setAspectRatio(aspectRatio); viewFrustum.setAspectRatio(aspectRatio);
viewFrustum.setFieldOfView(fov); viewFrustum.setFieldOfView(fov); // degrees
viewFrustum.setNearClip(nearClip); viewFrustum.setNearClip(nearClip);
viewFrustum.setFarClip(farClip); viewFrustum.setFarClip(farClip);
viewFrustum.setEyeOffsetPosition(camera.getEyeOffsetPosition()); viewFrustum.setEyeOffsetPosition(camera.getEyeOffsetPosition());
@ -2195,7 +2195,7 @@ void Application::updateShadowMap() {
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
glm::vec3 axis = glm::axis(rotation); glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
// store view matrix without translation, which we'll use for precision-sensitive objects // store view matrix without translation, which we'll use for precision-sensitive objects
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix);
@ -2274,7 +2274,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
glm::vec3 eyeOffsetPos = whichCamera.getEyeOffsetPosition(); glm::vec3 eyeOffsetPos = whichCamera.getEyeOffsetPosition();
glm::quat eyeOffsetOrient = whichCamera.getEyeOffsetOrientation(); glm::quat eyeOffsetOrient = whichCamera.getEyeOffsetOrientation();
glm::vec3 eyeOffsetAxis = glm::axis(eyeOffsetOrient); glm::vec3 eyeOffsetAxis = glm::axis(eyeOffsetOrient);
glRotatef(-glm::angle(eyeOffsetOrient), eyeOffsetAxis.x, eyeOffsetAxis.y, eyeOffsetAxis.z); glRotatef(-glm::degrees(glm::angle(eyeOffsetOrient)), eyeOffsetAxis.x, eyeOffsetAxis.y, eyeOffsetAxis.z);
glTranslatef(-eyeOffsetPos.x, -eyeOffsetPos.y, -eyeOffsetPos.z); glTranslatef(-eyeOffsetPos.x, -eyeOffsetPos.y, -eyeOffsetPos.z);
// transform view according to whichCamera // transform view according to whichCamera
@ -2283,7 +2283,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
glm::quat rotation = whichCamera.getRotation(); glm::quat rotation = whichCamera.getRotation();
glm::vec3 axis = glm::axis(rotation); glm::vec3 axis = glm::axis(rotation);
glRotatef(-glm::angle(rotation), axis.x, axis.y, axis.z); glRotatef(-glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
// store view matrix without translation, which we'll use for precision-sensitive objects // store view matrix without translation, which we'll use for precision-sensitive objects
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix);
@ -2501,7 +2501,7 @@ void Application::displayOverlay() {
(Menu::getInstance()->isOptionChecked(MenuOption::Stats) && (Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth)) Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth))
? 80 : 20; ? 80 : 20;
drawText(_glWidget->width() - 100, _glWidget->height() - timerBottom, 0.30f, 1.0f, 0, frameTimer, WHITE_TEXT); drawText(_glWidget->width() - 100, _glWidget->height() - timerBottom, 0.30f, 1.0f, 0.f, frameTimer, WHITE_TEXT);
} }
_overlays.render2D(); _overlays.render2D();
@ -2556,11 +2556,11 @@ void Application::displayStats() {
sprintf(framesPerSecond, "Framerate: %3.0f FPS", _fps); sprintf(framesPerSecond, "Framerate: %3.0f FPS", _fps);
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, serverNodes, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, serverNodes, WHITE_TEXT);
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarNodes, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarNodes, WHITE_TEXT);
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, framesPerSecond, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, framesPerSecond, WHITE_TEXT);
if (_statsExpanded) { if (_statsExpanded) {
char packetsPerSecond[30]; char packetsPerSecond[30];
@ -2569,9 +2569,9 @@ void Application::displayStats() {
sprintf(averageMegabitsPerSecond, "Mbps: %3.2f", (float)_bytesPerSecond * 8.f / 1000000.f); sprintf(averageMegabitsPerSecond, "Mbps: %3.2f", (float)_bytesPerSecond * 8.f / 1000000.f);
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, packetsPerSecond, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, packetsPerSecond, WHITE_TEXT);
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, averageMegabitsPerSecond, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, averageMegabitsPerSecond, WHITE_TEXT);
} }
verticalOffset = 0; verticalOffset = 0;
@ -2614,7 +2614,7 @@ void Application::displayStats() {
"Buffer msecs %.1f", "Buffer msecs %.1f",
(float) (_audio.getNetworkBufferLengthSamplesPerChannel() + (float) _audio.getJitterBufferSamples()) / (float) (_audio.getNetworkBufferLengthSamplesPerChannel() + (float) _audio.getJitterBufferSamples()) /
(float)_audio.getNetworkSampleRate() * 1000.f); (float)_audio.getNetworkSampleRate() * 1000.f);
drawText(30, _glWidget->height() - 22, 0.10f, 0, 2, audioJitter, WHITE_TEXT); drawText(30, _glWidget->height() - 22, 0.10f, 0.f, 2.f, audioJitter, WHITE_TEXT);
char audioPing[30]; char audioPing[30];
@ -2627,18 +2627,18 @@ void Application::displayStats() {
sprintf(voxelAvgPing, "Voxel avg ping: %d", pingVoxel); sprintf(voxelAvgPing, "Voxel avg ping: %d", pingVoxel);
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, audioPing, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, audioPing, WHITE_TEXT);
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarPing, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarPing, WHITE_TEXT);
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, voxelAvgPing, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, voxelAvgPing, WHITE_TEXT);
if (_statsExpanded) { if (_statsExpanded) {
char voxelMaxPing[30]; char voxelMaxPing[30];
sprintf(voxelMaxPing, "Voxel max ping: %d", pingVoxelMax); sprintf(voxelMaxPing, "Voxel max ping: %d", pingVoxelMax);
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, voxelMaxPing, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, voxelMaxPing, WHITE_TEXT);
} }
verticalOffset = 0; verticalOffset = 0;
@ -2666,11 +2666,11 @@ void Application::displayStats() {
char avatarMixerStats[200]; char avatarMixerStats[200];
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarPosition, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarPosition, WHITE_TEXT);
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarVelocity, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarVelocity, WHITE_TEXT);
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarBodyYaw, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarBodyYaw, WHITE_TEXT);
if (_statsExpanded) { if (_statsExpanded) {
SharedNodePointer avatarMixer = NodeList::getInstance()->soloNodeOfType(NodeType::AvatarMixer); SharedNodePointer avatarMixer = NodeList::getInstance()->soloNodeOfType(NodeType::AvatarMixer);
@ -2683,7 +2683,7 @@ void Application::displayStats() {
} }
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarMixerStats, WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarMixerStats, WHITE_TEXT);
} }
verticalOffset = 0; verticalOffset = 0;
@ -2698,7 +2698,7 @@ void Application::displayStats() {
voxelStats.str(""); voxelStats.str("");
voxelStats << "Voxels Memory Nodes: " << VoxelTreeElement::getTotalMemoryUsage() / 1000000.f << "MB"; voxelStats << "Voxels Memory Nodes: " << VoxelTreeElement::getTotalMemoryUsage() / 1000000.f << "MB";
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
voxelStats.str(""); voxelStats.str("");
voxelStats << voxelStats <<
@ -2708,14 +2708,14 @@ void Application::displayStats() {
voxelStats << " / GPU: " << _voxels.getVoxelMemoryUsageGPU() / 1000000.f << "MB"; voxelStats << " / GPU: " << _voxels.getVoxelMemoryUsageGPU() / 1000000.f << "MB";
} }
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
// Voxel Rendering // Voxel Rendering
voxelStats.str(""); voxelStats.str("");
voxelStats.precision(4); voxelStats.precision(4);
voxelStats << "Voxel Rendering Slots Max: " << _voxels.getMaxVoxels() / 1000.f << "K"; voxelStats << "Voxel Rendering Slots Max: " << _voxels.getMaxVoxels() / 1000.f << "K";
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
} }
voxelStats.str(""); voxelStats.str("");
@ -2723,7 +2723,7 @@ void Application::displayStats() {
voxelStats << "Drawn: " << _voxels.getVoxelsWritten() / 1000.f << "K " << voxelStats << "Drawn: " << _voxels.getVoxelsWritten() / 1000.f << "K " <<
"Abandoned: " << _voxels.getAbandonedVoxels() / 1000.f << "K "; "Abandoned: " << _voxels.getAbandonedVoxels() / 1000.f << "K ";
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
// iterate all the current voxel stats, and list their sending modes, and total voxel counts // iterate all the current voxel stats, and list their sending modes, and total voxel counts
std::stringstream sendingMode(""); std::stringstream sendingMode("");
@ -2767,7 +2767,7 @@ void Application::displayStats() {
sendingMode << " <SCENE STABLE>"; sendingMode << " <SCENE STABLE>";
} }
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)sendingMode.str().c_str(), WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)sendingMode.str().c_str(), WHITE_TEXT);
} }
// Incoming packets // Incoming packets
@ -2779,7 +2779,7 @@ void Application::displayStats() {
voxelStats << "Voxel Packets to Process: " << packetsString.toLocal8Bit().constData() voxelStats << "Voxel Packets to Process: " << packetsString.toLocal8Bit().constData()
<< " [Recent Max: " << maxString.toLocal8Bit().constData() << "]"; << " [Recent Max: " << maxString.toLocal8Bit().constData() << "]";
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
} }
if (_resetRecentMaxPacketsSoon && voxelPacketsToProcess > 0) { if (_resetRecentMaxPacketsSoon && voxelPacketsToProcess > 0) {
@ -2802,7 +2802,7 @@ void Application::displayStats() {
voxelStats.str(""); voxelStats.str("");
voxelStats << "Server voxels: " << serversTotalString.toLocal8Bit().constData(); voxelStats << "Server voxels: " << serversTotalString.toLocal8Bit().constData();
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
if (_statsExpanded) { if (_statsExpanded) {
QString serversInternalString = locale.toString((uint)totalInternal); QString serversInternalString = locale.toString((uint)totalInternal);
@ -2813,7 +2813,7 @@ void Application::displayStats() {
"Internal: " << serversInternalString.toLocal8Bit().constData() << " " << "Internal: " << serversInternalString.toLocal8Bit().constData() << " " <<
"Leaves: " << serversLeavesString.toLocal8Bit().constData() << ""; "Leaves: " << serversLeavesString.toLocal8Bit().constData() << "";
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
} }
unsigned long localTotal = VoxelTreeElement::getNodeCount(); unsigned long localTotal = VoxelTreeElement::getNodeCount();
@ -2823,7 +2823,7 @@ void Application::displayStats() {
voxelStats.str(""); voxelStats.str("");
voxelStats << "Local voxels: " << localTotalString.toLocal8Bit().constData(); voxelStats << "Local voxels: " << localTotalString.toLocal8Bit().constData();
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
if (_statsExpanded) { if (_statsExpanded) {
unsigned long localInternal = VoxelTreeElement::getInternalNodeCount(); unsigned long localInternal = VoxelTreeElement::getInternalNodeCount();
@ -2836,7 +2836,7 @@ void Application::displayStats() {
"Internal: " << localInternalString.toLocal8Bit().constData() << " " << "Internal: " << localInternalString.toLocal8Bit().constData() << " " <<
"Leaves: " << localLeavesString.toLocal8Bit().constData() << ""; "Leaves: " << localLeavesString.toLocal8Bit().constData() << "";
verticalOffset += STATS_PELS_PER_LINE; verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT); drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
} }
} }
@ -2927,17 +2927,17 @@ glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {
void Application::renderRearViewMirror(const QRect& region, bool billboard) { void Application::renderRearViewMirror(const QRect& region, bool billboard) {
bool eyeRelativeCamera = false; bool eyeRelativeCamera = false;
if (billboard) { if (billboard) {
_mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); _mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees
_mirrorCamera.setDistance(BILLBOARD_DISTANCE * _myAvatar->getScale()); _mirrorCamera.setDistance(BILLBOARD_DISTANCE * _myAvatar->getScale());
_mirrorCamera.setTargetPosition(_myAvatar->getPosition()); _mirrorCamera.setTargetPosition(_myAvatar->getPosition());
} else if (_rearMirrorTools->getZoomLevel() == BODY) { } else if (_rearMirrorTools->getZoomLevel() == BODY) {
_mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees
_mirrorCamera.setDistance(MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); _mirrorCamera.setDistance(MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale());
_mirrorCamera.setTargetPosition(_myAvatar->getChestPosition()); _mirrorCamera.setTargetPosition(_myAvatar->getChestPosition());
} else { // HEAD zoom level } else { // HEAD zoom level
_mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees
_mirrorCamera.setDistance(MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); _mirrorCamera.setDistance(MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());
if (_myAvatar->getSkeletonModel().isActive() && _myAvatar->getHead()->getFaceModel().isActive()) { if (_myAvatar->getSkeletonModel().isActive() && _myAvatar->getHead()->getFaceModel().isActive()) {
// as a hack until we have a better way of dealing with coordinate precision issues, reposition the // as a hack until we have a better way of dealing with coordinate precision issues, reposition the
@ -2951,7 +2951,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
} }
_mirrorCamera.setAspectRatio((float)region.width() / region.height()); _mirrorCamera.setAspectRatio((float)region.width() / region.height());
_mirrorCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PIf, 0.0f))); _mirrorCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f)));
_mirrorCamera.update(1.0f/_fps); _mirrorCamera.update(1.0f/_fps);
// set the bounds of rear mirror view // set the bounds of rear mirror view

View file

@ -95,8 +95,8 @@ static const float NODE_KILLED_BLUE = 0.0f;
static const QString SNAPSHOT_EXTENSION = ".jpg"; static const QString SNAPSHOT_EXTENSION = ".jpg";
static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees
static const float BILLBOARD_DISTANCE = 5.0f; static const float BILLBOARD_DISTANCE = 5.0f; // meters
class Application : public QApplication { class Application : public QApplication {
Q_OBJECT Q_OBJECT

View file

@ -20,7 +20,6 @@
#include <QtMultimedia/QAudioOutput> #include <QtMultimedia/QAudioOutput>
#include <QSvgRenderer> #include <QSvgRenderer>
#include <AngleUtil.h>
#include <NodeList.h> #include <NodeList.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include <SharedUtil.h> #include <SharedUtil.h>
@ -656,7 +655,7 @@ void Audio::addProceduralSounds(int16_t* monoInput, int numSamples) {
const float MAX_DURATION = 2.f; const float MAX_DURATION = 2.f;
const float MIN_AUDIBLE_VOLUME = 0.001f; const float MIN_AUDIBLE_VOLUME = 0.001f;
const float NOISE_MAGNITUDE = 0.02f; const float NOISE_MAGNITUDE = 0.02f;
float frequency = (_drumSoundFrequency / SAMPLE_RATE) * PI_TIMES_TWO; float frequency = (_drumSoundFrequency / SAMPLE_RATE) * TWO_PI;
if (_drumSoundVolume > 0.f) { if (_drumSoundVolume > 0.f) {
for (int i = 0; i < numSamples; i++) { for (int i = 0; i < numSamples; i++) {
t = (float) _drumSoundSample + (float) i; t = (float) _drumSoundSample + (float) i;

View file

@ -81,7 +81,7 @@ void Camera::updateFollowMode(float deltaTime) {
_distance = _newDistance; _distance = _newDistance;
_tightness = _newTightness; _tightness = _newTightness;
} else { } else {
_modeShift = ONE_HALF - ONE_HALF * cosf(_linearModeShift * PIE ); _modeShift = ONE_HALF - ONE_HALF * cosf(_linearModeShift * PI );
_upShift = _previousUpShift * (1.0f - _modeShift) + _newUpShift * _modeShift; _upShift = _previousUpShift * (1.0f - _modeShift) + _newUpShift * _modeShift;
_distance = _previousDistance * (1.0f - _modeShift) + _newDistance * _modeShift; _distance = _previousDistance * (1.0f - _modeShift) + _newDistance * _modeShift;
_tightness = _previousTightness * (1.0f - _modeShift) + _newTightness * _modeShift; _tightness = _previousTightness * (1.0f - _modeShift) + _newTightness * _modeShift;

View file

@ -89,7 +89,7 @@ private:
glm::vec3 _position; glm::vec3 _position;
glm::vec3 _idealPosition; glm::vec3 _idealPosition;
glm::vec3 _targetPosition; glm::vec3 _targetPosition;
float _fieldOfView; float _fieldOfView; // degrees
float _aspectRatio; float _aspectRatio;
float _nearClip; float _nearClip;
float _farClip; float _farClip;

View file

@ -237,8 +237,8 @@ void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data)
program->setUniformValue(locations[INNER_RADIUS_LOCATION], data.getAtmosphereInnerRadius()); program->setUniformValue(locations[INNER_RADIUS_LOCATION], data.getAtmosphereInnerRadius());
program->setUniformValue(locations[KR_ESUN_LOCATION], data.getRayleighScattering() * data.getSunBrightness()); program->setUniformValue(locations[KR_ESUN_LOCATION], data.getRayleighScattering() * data.getSunBrightness());
program->setUniformValue(locations[KM_ESUN_LOCATION], data.getMieScattering() * data.getSunBrightness()); program->setUniformValue(locations[KM_ESUN_LOCATION], data.getMieScattering() * data.getSunBrightness());
program->setUniformValue(locations[KR_4PI_LOCATION], data.getRayleighScattering() * 4.0f * PIf); program->setUniformValue(locations[KR_4PI_LOCATION], data.getRayleighScattering() * 4.0f * PI);
program->setUniformValue(locations[KM_4PI_LOCATION], data.getMieScattering() * 4.0f * PIf); program->setUniformValue(locations[KM_4PI_LOCATION], data.getMieScattering() * 4.0f * PI);
program->setUniformValue(locations[SCALE_LOCATION], 1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())); program->setUniformValue(locations[SCALE_LOCATION], 1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius()));
program->setUniformValue(locations[SCALE_DEPTH_LOCATION], 0.25f); program->setUniformValue(locations[SCALE_DEPTH_LOCATION], 0.25f);
program->setUniformValue(locations[SCALE_OVER_SCALE_DEPTH_LOCATION], program->setUniformValue(locations[SCALE_OVER_SCALE_DEPTH_LOCATION],

View file

@ -699,8 +699,8 @@ void Menu::editPreferences() {
form->addRow("Faceshift Eye Deflection:", faceshiftEyeDeflection); form->addRow("Faceshift Eye Deflection:", faceshiftEyeDeflection);
QSpinBox* fieldOfView = new QSpinBox(); QSpinBox* fieldOfView = new QSpinBox();
fieldOfView->setMaximum(180); fieldOfView->setMaximum(180.f);
fieldOfView->setMinimum(1); fieldOfView->setMinimum(1.f);
fieldOfView->setValue(_fieldOfView); fieldOfView->setValue(_fieldOfView);
form->addRow("Vertical Field of View (Degrees):", fieldOfView); form->addRow("Vertical Field of View (Degrees):", fieldOfView);

View file

@ -139,7 +139,7 @@ public:
private slots: private slots:
void applyTranslation(const glm::vec3& translation); void applyTranslation(const glm::vec3& translation);
void applyRotation(const glm::vec3& rotation); void applyRotation(const glm::vec3& eulerAngles); // eulerAngles are in degrees
void applyScale(float scale); void applyScale(float scale);
void applyURL(const QUrl& url); void applyURL(const QUrl& url);

View file

@ -30,9 +30,8 @@ bool Stars::setResolution(unsigned k) {
} }
void Stars::render(float fovY, float aspect, float nearZ, float alpha) { void Stars::render(float fovY, float aspect, float nearZ, float alpha) {
// determine length of screen diagonal from quadrant height and aspect ratio // determine length of screen diagonal from quadrant height and aspect ratio
float quadrantHeight = nearZ * tan(angleConvert<Degrees,Radians>(fovY) * 0.5f); float quadrantHeight = nearZ * tan(RADIANS_PER_DEGREE * fovY * 0.5f);
float halfDiagonal = sqrt(quadrantHeight * quadrantHeight * (1.0f + aspect * aspect)); float halfDiagonal = sqrt(quadrantHeight * quadrantHeight * (1.0f + aspect * aspect));
// determine fov angle in respect to the diagonal // determine fov angle in respect to the diagonal

View file

@ -68,19 +68,21 @@ void printVector(glm::vec3 vec) {
printf("%4.2f, %4.2f, %4.2f\n", vec.x, vec.y, vec.z); printf("%4.2f, %4.2f, %4.2f\n", vec.x, vec.y, vec.z);
} }
// Return the azimuth angle in degrees between two points. // Return the azimuth angle (in radians) between two points.
float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos) { float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos) {
return atan2(head_pos.x - source_pos.x, head_pos.z - source_pos.z) * 180.0f / PIf; return atan2(head_pos.x - source_pos.x, head_pos.z - source_pos.z);
} }
// Return the angle in degrees between the head and an object in the scene. The value is zero if you are looking right at it. The angle is negative if the object is to your right. // Return the angle (in radians) between the head and an object in the scene.
// The value is zero if you are looking right at it.
// The angle is negative if the object is to your right.
float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float head_yaw) { float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float head_yaw) {
return atan2(head_pos.x - source_pos.x, head_pos.z - source_pos.z) * 180.0f / PIf + render_yaw + head_yaw; return atan2(head_pos.x - source_pos.x, head_pos.z - source_pos.z) + render_yaw + head_yaw;
} }
// Helper function returns the positive angle in degrees between two 3D vectors // Helper function returns the positive angle (in radians) between two 3D vectors
float angleBetween(const glm::vec3& v1, const glm::vec3& v2) { float angleBetween(const glm::vec3& v1, const glm::vec3& v2) {
return acos((glm::dot(v1, v2)) / (glm::length(v1) * glm::length(v2))) * 180.f / PIf; return acosf((glm::dot(v1, v2)) / (glm::length(v1) * glm::length(v2)));
} }
// Helper function return the rotation from the first vector onto the second // Helper function return the rotation from the first vector onto the second
@ -90,7 +92,7 @@ glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2) {
return glm::quat(); return glm::quat();
} }
glm::vec3 axis; glm::vec3 axis;
if (angle > 179.99f) { // 180 degree rotation; must use another axis if (angle > 179.99f * RADIANS_PER_DEGREE) { // 180 degree rotation; must use another axis
axis = glm::cross(v1, glm::vec3(1.0f, 0.0f, 0.0f)); axis = glm::cross(v1, glm::vec3(1.0f, 0.0f, 0.0f));
float axisLength = glm::length(axis); float axisLength = glm::length(axis);
if (axisLength < EPSILON) { // parallel to x; y will work if (axisLength < EPSILON) { // parallel to x; y will work
@ -314,7 +316,7 @@ float widthChar(float scale, int mono, char ch) {
return textRenderer(mono)->computeWidth(ch) * (scale / 0.10); return textRenderer(mono)->computeWidth(ch) * (scale / 0.10);
} }
void drawText(int x, int y, float scale, float rotate, int mono, void drawText(int x, int y, float scale, float radians, int mono,
char const* string, const float* color) { char const* string, const float* color) {
// //
// Draws text on screen as stroked so it can be resized // Draws text on screen as stroked so it can be resized
@ -322,16 +324,16 @@ void drawText(int x, int y, float scale, float rotate, int mono,
glPushMatrix(); glPushMatrix();
glTranslatef(static_cast<float>(x), static_cast<float>(y), 0.0f); glTranslatef(static_cast<float>(x), static_cast<float>(y), 0.0f);
glColor3fv(color); glColor3fv(color);
glRotated(rotate,0,0,1); glRotated(double(radians * DEGREES_PER_RADIAN), 0.0, 0.0, 1.0);
glScalef(scale / 0.10, scale / 0.10, 1.0); glScalef(scale / 0.1f, scale / 0.1f, 1.f);
textRenderer(mono)->draw(0, 0, string); textRenderer(mono)->draw(0, 0, string);
glPopMatrix(); glPopMatrix();
} }
void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec, float r, float g, float b) { void drawvec3(int x, int y, float scale, float radians, float thick, int mono, glm::vec3 vec, float r, float g, float b) {
// //
// Draws text on screen as stroked so it can be resized // Draws vec3 on screen as stroked so it can be resized
// //
char vectext[20]; char vectext[20];
sprintf(vectext,"%3.1f,%3.1f,%3.1f", vec.x, vec.y, vec.z); sprintf(vectext,"%3.1f,%3.1f,%3.1f", vec.x, vec.y, vec.z);
@ -339,10 +341,10 @@ void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, gl
glPushMatrix(); glPushMatrix();
glTranslatef(static_cast<float>(x), static_cast<float>(y), 0); glTranslatef(static_cast<float>(x), static_cast<float>(y), 0);
glColor3f(r,g,b); glColor3f(r,g,b);
glRotated(180+rotate,0,0,1); glRotated(180.0 + double(radians * DEGREES_PER_RADIAN), 0.0, 0.0, 1.0);
glRotated(180,0,1,0); glRotated(180.0, 0.0, 1.0, 0.0);
glLineWidth(thick); glLineWidth(thick);
glScalef(scale, scale, 1.0); glScalef(scale, scale, 1.f);
len = (int) strlen(vectext); len = (int) strlen(vectext);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (!mono) glutStrokeCharacter(GLUT_STROKE_ROMAN, int(vectext[i])); if (!mono) glutStrokeCharacter(GLUT_STROKE_ROMAN, int(vectext[i]));
@ -371,9 +373,9 @@ void renderSphereOutline(glm::vec3 position, float radius, int numSides, glm::ve
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
for (int i=0; i<numSides+1; i++) { for (int i=0; i<numSides+1; i++) {
float r = ((float)i / (float)numSides) * PIf * 2.0; float r = ((float)i / (float)numSides) * TWO_PI;
float s = radius * sin(r); float s = radius * sinf(r);
float c = radius * cos(r); float c = radius * cosf(r);
glVertex3f glVertex3f
( (
@ -394,9 +396,9 @@ void renderCircle(glm::vec3 position, float radius, glm::vec3 surfaceNormal, int
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
for (int i=0; i<numSides+1; i++) { for (int i=0; i<numSides+1; i++) {
float r = ((float)i / (float)numSides) * PIf * 2.0; float r = ((float)i / (float)numSides) * TWO_PI;
float s = radius * sin(r); float s = radius * sinf(r);
float c = radius * cos(r); float c = radius * cosf(r);
glVertex3f glVertex3f
( (
position.x + perp1.x * s + perp2.x * c, position.x + perp1.x * s + perp2.x * c,
@ -440,12 +442,12 @@ void renderRoundedCornersRect(int x, int y, int width, int height, int radius, i
numPointsCorner = MAX_POINTS_CORNER; numPointsCorner = MAX_POINTS_CORNER;
} }
// Precompute sin and cos for [0, pi/2) for the number of points (numPointCorner) // Precompute sin and cos for [0, PI/2) for the number of points (numPointCorner)
double radiusTimesSin[MAX_POINTS_CORNER]; double radiusTimesSin[MAX_POINTS_CORNER];
double radiusTimesCos[MAX_POINTS_CORNER]; double radiusTimesCos[MAX_POINTS_CORNER];
int i = 0; int i = 0;
for (int i = 0; i < numPointsCorner; i++) { for (int i = 0; i < numPointsCorner; i++) {
double t = i * PIf / (2.0f * (numPointsCorner - 1)); double t = (double)i * (double)PI_OVER_TWO / (double)(numPointsCorner - 1);
radiusTimesSin[i] = radius * sin(t); radiusTimesSin[i] = radius * sin(t);
radiusTimesCos[i] = radius * cos(t); radiusTimesCos[i] = radius * cos(t);
} }

View file

@ -31,10 +31,10 @@ void renderWorldBox();
int widthText(float scale, int mono, char const* string); int widthText(float scale, int mono, char const* string);
float widthChar(float scale, int mono, char ch); float widthChar(float scale, int mono, char ch);
void drawText(int x, int y, float scale, float rotate, int mono, void drawText(int x, int y, float scale, float radians, int mono,
char const* string, const float* color); char const* string, const float* color);
void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec, void drawvec3(int x, int y, float scale, float radians, float thick, int mono, glm::vec3 vec,
float r=1.0, float g=1.0, float b=1.0); float r=1.0, float g=1.0, float b=1.0);
void drawVector(glm::vec3* vector); void drawVector(glm::vec3* vector);

View file

@ -229,8 +229,8 @@ void Avatar::render(bool forShadowMap) {
} }
// render voice intensity sphere for avatars that are farther away // render voice intensity sphere for avatars that are farther away
const float MAX_SPHERE_ANGLE = 10.f; const float MAX_SPHERE_ANGLE = 10.f * RADIANS_PER_DEGREE;
const float MIN_SPHERE_ANGLE = 1.f; const float MIN_SPHERE_ANGLE = 1.f * RADIANS_PER_DEGREE;
const float MIN_SPHERE_SIZE = 0.01f; const float MIN_SPHERE_SIZE = 0.01f;
const float SPHERE_LOUDNESS_SCALING = 0.0005f; const float SPHERE_LOUDNESS_SCALING = 0.0005f;
const float SPHERE_COLOR[] = { 0.5f, 0.8f, 0.8f }; const float SPHERE_COLOR[] = { 0.5f, 0.8f, 0.8f };
@ -267,12 +267,12 @@ void Avatar::render(bool forShadowMap) {
glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z); glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z);
glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation(); glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation();
glm::vec3 chatAxis = glm::axis(chatRotation); glm::vec3 chatAxis = glm::axis(chatRotation);
glRotatef(glm::angle(chatRotation), chatAxis.x, chatAxis.y, chatAxis.z); glRotatef(glm::degrees(glm::angle(chatRotation)), chatAxis.x, chatAxis.y, chatAxis.z);
glColor3f(0, 0.8f, 0); glColor3f(0.f, 0.8f, 0.f);
glRotatef(180, 0, 1, 0); glRotatef(180.f, 0.f, 1.f, 0.f);
glRotatef(180, 0, 0, 1); glRotatef(180.f, 0.f, 0.f, 1.f);
glScalef(_scale * CHAT_MESSAGE_SCALE, _scale * CHAT_MESSAGE_SCALE, 1.0f); glScalef(_scale * CHAT_MESSAGE_SCALE, _scale * CHAT_MESSAGE_SCALE, 1.0f);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
@ -288,7 +288,7 @@ void Avatar::render(bool forShadowMap) {
_chatMessage[lastIndex] = '\0'; _chatMessage[lastIndex] = '\0';
textRenderer(CHAT)->draw(-width / 2.0f, 0, _chatMessage.c_str()); textRenderer(CHAT)->draw(-width / 2.0f, 0, _chatMessage.c_str());
_chatMessage[lastIndex] = lastChar; _chatMessage[lastIndex] = lastChar;
glColor3f(0, 1, 0); glColor3f(0.f, 1.f, 0.f);
textRenderer(CHAT)->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex); textRenderer(CHAT)->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex);
} }
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
@ -301,12 +301,12 @@ void Avatar::render(bool forShadowMap) {
glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {
glm::quat orientation = getOrientation(); glm::quat orientation = getOrientation();
glm::vec3 currentUp = orientation * IDENTITY_UP; glm::vec3 currentUp = orientation * IDENTITY_UP;
float angle = glm::degrees(acosf(glm::clamp(glm::dot(currentUp, _worldUpDirection), -1.0f, 1.0f))); float angle = acosf(glm::clamp(glm::dot(currentUp, _worldUpDirection), -1.0f, 1.0f));
if (angle < EPSILON) { if (angle < EPSILON) {
return glm::quat(); return glm::quat();
} }
glm::vec3 axis; glm::vec3 axis;
if (angle > 179.99f) { // 180 degree rotation; must use another axis if (angle > 179.99f * RADIANS_PER_DEGREE) { // 180 degree rotation; must use another axis
axis = orientation * IDENTITY_RIGHT; axis = orientation * IDENTITY_RIGHT;
} else { } else {
axis = glm::normalize(glm::cross(currentUp, _worldUpDirection)); axis = glm::normalize(glm::cross(currentUp, _worldUpDirection));
@ -356,9 +356,9 @@ void Avatar::renderBillboard() {
// rotate about vertical to face the camera // rotate about vertical to face the camera
glm::quat rotation = getOrientation(); glm::quat rotation = getOrientation();
glm::vec3 cameraVector = glm::inverse(rotation) * (Application::getInstance()->getCamera()->getPosition() - _position); glm::vec3 cameraVector = glm::inverse(rotation) * (Application::getInstance()->getCamera()->getPosition() - _position);
rotation = rotation * glm::angleAxis(glm::degrees(atan2f(-cameraVector.x, -cameraVector.z)), glm::vec3(0.0f, 1.0f, 0.0f)); rotation = rotation * glm::angleAxis(atan2f(-cameraVector.x, -cameraVector.z), glm::vec3(0.0f, 1.0f, 0.0f));
glm::vec3 axis = glm::axis(rotation); glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
// compute the size from the billboard camera parameters and scale // compute the size from the billboard camera parameters and scale
float size = _scale * BILLBOARD_DISTANCE * tanf(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f)); float size = _scale * BILLBOARD_DISTANCE * tanf(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f));
@ -404,7 +404,7 @@ void Avatar::renderDisplayName() {
// we need "always facing camera": we must remove the camera rotation from the stack // we need "always facing camera": we must remove the camera rotation from the stack
glm::quat rotation = Application::getInstance()->getCamera()->getRotation(); glm::quat rotation = Application::getInstance()->getCamera()->getRotation();
glm::vec3 axis = glm::axis(rotation); glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
// We need to compute the scale factor such as the text remains with fixed size respect to window coordinates // We need to compute the scale factor such as the text remains with fixed size respect to window coordinates
// We project a unit vector and check the difference in screen coordinates, to check which is the // We project a unit vector and check the difference in screen coordinates, to check which is the
@ -662,15 +662,15 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2,
glm::vec3 perpCos = glm::normalize(glm::cross(axis, perpSin)); glm::vec3 perpCos = glm::normalize(glm::cross(axis, perpSin));
perpSin = glm::cross(perpCos, axis); perpSin = glm::cross(perpCos, axis);
float anglea = 0.0; float anglea = 0.f;
float angleb = 0.0; float angleb = 0.f;
for (int i = 0; i < NUM_BODY_CONE_SIDES; i ++) { for (int i = 0; i < NUM_BODY_CONE_SIDES; i ++) {
// the rectangles that comprise the sides of the cone section are // the rectangles that comprise the sides of the cone section are
// referenced by "a" and "b" in one dimension, and "1", and "2" in the other dimension. // referenced by "a" and "b" in one dimension, and "1", and "2" in the other dimension.
anglea = angleb; anglea = angleb;
angleb = ((float)(i+1) / (float)NUM_BODY_CONE_SIDES) * PIf * 2.0f; angleb = ((float)(i+1) / (float)NUM_BODY_CONE_SIDES) * TWO_PI;
float sa = sinf(anglea); float sa = sinf(anglea);
float sb = sinf(angleb); float sb = sinf(angleb);

View file

@ -56,9 +56,10 @@ void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBX
glm::mat3 axes = glm::mat3_cast(_rotation); glm::mat3 axes = glm::mat3_cast(_rotation);
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) * glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) *
joint.preTransform * glm::mat4_cast(joint.preRotation))); joint.preTransform * glm::mat4_cast(joint.preRotation)));
state.rotation = glm::angleAxis(-_owningHead->getTweakedRoll(), glm::normalize(inverse * axes[2])) * state.rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getTweakedRoll(), glm::normalize(inverse * axes[2]))
glm::angleAxis(_owningHead->getTweakedYaw(), glm::normalize(inverse * axes[1])) * * glm::angleAxis(RADIANS_PER_DEGREE * _owningHead->getTweakedYaw(), glm::normalize(inverse * axes[1]))
glm::angleAxis(-_owningHead->getTweakedPitch(), glm::normalize(inverse * axes[0])) * joint.rotation; * glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getTweakedPitch(), glm::normalize(inverse * axes[0]))
* joint.rotation;
} }
void FaceModel::maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) { void FaceModel::maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
@ -69,7 +70,7 @@ void FaceModel::maybeUpdateEyeRotation(const JointState& parentState, const FBXJ
glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getLookAtPosition() + glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getLookAtPosition() +
_owningHead->getSaccade() - _translation, 1.0f)); _owningHead->getSaccade() - _translation, 1.0f));
glm::quat between = rotationBetween(front, lookAt); glm::quat between = rotationBetween(front, lookAt);
const float MAX_ANGLE = 30.0f; const float MAX_ANGLE = 30.0f * RADIANS_PER_DEGREE;
state.rotation = glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) * state.rotation = glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) *
joint.rotation; joint.rotation;
} }

View file

@ -183,13 +183,13 @@ void Head::setScale (float scale) {
} }
glm::quat Head::getTweakedOrientation() const { glm::quat Head::getTweakedOrientation() const {
return _owningAvatar->getOrientation() * glm::quat(glm::radians(glm::vec3(getTweakedPitch(), getTweakedYaw(), getTweakedRoll() ))); return _owningAvatar->getOrientation() * glm::quat(glm::radians(
glm::vec3(getTweakedPitch(), getTweakedYaw(), getTweakedRoll() )));
} }
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(_pitch, 0.f, 0.0f)));
* glm::quat(glm::radians(glm::vec3(_pitch, 0.f, 0.0f)));
} }
glm::quat Head::getEyeRotation(const glm::vec3& eyePosition) const { glm::quat Head::getEyeRotation(const glm::vec3& eyePosition) const {

View file

@ -34,8 +34,8 @@
using namespace std; using namespace std;
const glm::vec3 DEFAULT_UP_DIRECTION(0.0f, 1.0f, 0.0f); const glm::vec3 DEFAULT_UP_DIRECTION(0.0f, 1.0f, 0.0f);
const float YAW_MAG = 500.0f; const float YAW_SPEED = 500.0f; // degrees/sec
const float PITCH_MAG = 100.0f; const float PITCH_SPEED = 100.0f; // degrees/sec
const float COLLISION_RADIUS_SCALAR = 1.2f; // pertains to avatar-to-avatar collisions const float COLLISION_RADIUS_SCALAR = 1.2f; // pertains to avatar-to-avatar collisions
const float COLLISION_BODY_FORCE = 30.0f; // pertains to avatar-to-avatar collisions const float COLLISION_BODY_FORCE = 30.0f; // pertains to avatar-to-avatar collisions
const float COLLISION_RADIUS_SCALE = 0.125f; const float COLLISION_RADIUS_SCALE = 0.125f;
@ -118,12 +118,13 @@ void MyAvatar::update(float deltaTime) {
Head* head = getHead(); Head* head = getHead();
if (OculusManager::isConnected()) { if (OculusManager::isConnected()) {
float yaw, pitch, roll; float yaw, pitch, roll; // these angles will be in radians
OculusManager::getEulerAngles(yaw, pitch, roll); OculusManager::getEulerAngles(yaw, pitch, roll);
head->setYaw(yaw); // but these euler angles are stored in degrees
head->setPitch(pitch); head->setYaw(yaw * DEGREES_PER_RADIAN);
head->setRoll(roll); head->setPitch(pitch * DEGREES_PER_RADIAN);
head->setRoll(roll * DEGREES_PER_RADIAN);
} }
// Get audio loudness data from audio input device // Get audio loudness data from audio input device
@ -186,7 +187,7 @@ void MyAvatar::simulate(float deltaTime) {
float radius = getSkeletonHeight() * COLLISION_RADIUS_SCALE; float radius = getSkeletonHeight() * COLLISION_RADIUS_SCALE;
if (myCamera->getMode() == CAMERA_MODE_FIRST_PERSON && !OculusManager::isConnected()) { if (myCamera->getMode() == CAMERA_MODE_FIRST_PERSON && !OculusManager::isConnected()) {
radius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cos(myCamera->getFieldOfView() / 2.f)); radius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cosf(0.5f * RADIANS_PER_DEGREE * myCamera->getFieldOfView()));
radius *= COLLISION_RADIUS_SCALAR; radius *= COLLISION_RADIUS_SCALAR;
} }
@ -210,7 +211,7 @@ void MyAvatar::simulate(float deltaTime) {
// decay body rotation momentum // decay body rotation momentum
const float BODY_SPIN_FRICTION = 7.5f; const float BODY_SPIN_FRICTION = 7.5f;
float bodySpinMomentum = 1.0 - BODY_SPIN_FRICTION * deltaTime; float bodySpinMomentum = 1.f - BODY_SPIN_FRICTION * deltaTime;
if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; } if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; }
_bodyPitchDelta *= bodySpinMomentum; _bodyPitchDelta *= bodySpinMomentum;
_bodyYawDelta *= bodySpinMomentum; _bodyYawDelta *= bodySpinMomentum;
@ -340,12 +341,12 @@ void MyAvatar::updateFromGyros(float deltaTime) {
bool trackerActive = false; bool trackerActive = false;
if (faceshift->isActive()) { if (faceshift->isActive()) {
estimatedPosition = faceshift->getHeadTranslation(); estimatedPosition = faceshift->getHeadTranslation();
estimatedRotation = safeEulerAngles(faceshift->getHeadRotation()); estimatedRotation = DEGREES_PER_RADIAN * safeEulerAngles(faceshift->getHeadRotation());
trackerActive = true; trackerActive = true;
} else if (visage->isActive()) { } else if (visage->isActive()) {
estimatedPosition = visage->getHeadTranslation(); estimatedPosition = visage->getHeadTranslation();
estimatedRotation = safeEulerAngles(visage->getHeadRotation()); estimatedRotation = DEGREES_PER_RADIAN * safeEulerAngles(visage->getHeadRotation());
trackerActive = true; trackerActive = true;
} }
@ -492,12 +493,11 @@ void MyAvatar::render(bool forShadowMapOrMirror) {
glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z); glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z);
glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation(); glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation();
glm::vec3 chatAxis = glm::axis(chatRotation); glm::vec3 chatAxis = glm::axis(chatRotation);
glRotatef(glm::angle(chatRotation), chatAxis.x, chatAxis.y, chatAxis.z); glRotatef(glm::degrees(glm::angle(chatRotation)), chatAxis.x, chatAxis.y, chatAxis.z);
glColor3f(0.f, 0.8f, 0.f);
glColor3f(0, 0.8f, 0); glRotatef(180.f, 0.f, 1.f, 0.f);
glRotatef(180, 0, 1, 0); glRotatef(180.f, 0.f, 0.f, 1.f);
glRotatef(180, 0, 0, 1);
glScalef(_scale * CHAT_MESSAGE_SCALE, _scale * CHAT_MESSAGE_SCALE, 1.0f); glScalef(_scale * CHAT_MESSAGE_SCALE, _scale * CHAT_MESSAGE_SCALE, 1.0f);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
@ -513,7 +513,7 @@ void MyAvatar::render(bool forShadowMapOrMirror) {
_chatMessage[lastIndex] = '\0'; _chatMessage[lastIndex] = '\0';
textRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str()); textRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str());
_chatMessage[lastIndex] = lastChar; _chatMessage[lastIndex] = lastChar;
glColor3f(0, 1, 0); glColor3f(0.f, 1.f, 0.f);
textRenderer()->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex); textRenderer()->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex);
} }
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
@ -527,7 +527,7 @@ void MyAvatar::renderHeadMouse() const {
// TODO? resurrect headMouse stuff? // TODO? resurrect headMouse stuff?
/* /*
// Display small target box at center or head mouse target that can also be used to measure LOD // 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); glColor3f(1.f, 1.f, 1.f);
glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_SMOOTH);
const int PIXEL_BOX = 16; const int PIXEL_BOX = 16;
glBegin(GL_LINES); glBegin(GL_LINES);
@ -549,7 +549,7 @@ void MyAvatar::renderHeadMouse() const {
int eyeTargetX = (_glWidget->width() / 2) - _faceshift.getEstimatedEyeYaw() * EYE_TARGET_PIXELS_PER_DEGREE; int eyeTargetX = (_glWidget->width() / 2) - _faceshift.getEstimatedEyeYaw() * EYE_TARGET_PIXELS_PER_DEGREE;
int eyeTargetY = (_glWidget->height() / 2) - _faceshift.getEstimatedEyePitch() * EYE_TARGET_PIXELS_PER_DEGREE; int eyeTargetY = (_glWidget->height() / 2) - _faceshift.getEstimatedEyePitch() * EYE_TARGET_PIXELS_PER_DEGREE;
glColor3f(0.0, 1.0, 1.0); glColor3f(0.f, 1.f, 1.f);
glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_SMOOTH);
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex2f(eyeTargetX - PIXEL_BOX/2, eyeTargetY); glVertex2f(eyeTargetX - PIXEL_BOX/2, eyeTargetY);
@ -624,15 +624,15 @@ void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) {
// first orbit horizontally // first orbit horizontally
glm::quat orientation = getOrientation(); glm::quat orientation = getOrientation();
const float ANGULAR_SCALE = 0.5f; const float ANGULAR_SCALE = 0.5f;
glm::quat rotation = glm::angleAxis(deltaX * -ANGULAR_SCALE, orientation * IDENTITY_UP); glm::quat rotation = glm::angleAxis(glm::radians(- deltaX * ANGULAR_SCALE), orientation * IDENTITY_UP);
setPosition(position + rotation * (getPosition() - position)); setPosition(position + rotation * (getPosition() - position));
orientation = rotation * orientation; orientation = rotation * orientation;
setOrientation(orientation); setOrientation(orientation);
// then vertically // then vertically
float oldPitch = getHead()->getPitch(); float oldPitch = getHead()->getPitch();
getHead()->setPitch(oldPitch + deltaY * -ANGULAR_SCALE); getHead()->setPitch(oldPitch - deltaY * ANGULAR_SCALE);
rotation = glm::angleAxis(getHead()->getPitch() - oldPitch, orientation * IDENTITY_RIGHT); rotation = glm::angleAxis(glm::radians((getHead()->getPitch() - oldPitch)), orientation * IDENTITY_RIGHT);
setPosition(position + rotation * (getPosition() - position)); setPosition(position + rotation * (getPosition() - position));
} }
@ -737,9 +737,9 @@ void MyAvatar::updateThrust(float deltaTime) {
_thrust -= _driveKeys[LEFT] * _scale * THRUST_MAG_LATERAL * _thrustMultiplier * deltaTime * right; _thrust -= _driveKeys[LEFT] * _scale * THRUST_MAG_LATERAL * _thrustMultiplier * deltaTime * right;
_thrust += _driveKeys[UP] * _scale * THRUST_MAG_UP * _thrustMultiplier * deltaTime * up; _thrust += _driveKeys[UP] * _scale * THRUST_MAG_UP * _thrustMultiplier * deltaTime * up;
_thrust -= _driveKeys[DOWN] * _scale * THRUST_MAG_DOWN * _thrustMultiplier * deltaTime * up; _thrust -= _driveKeys[DOWN] * _scale * THRUST_MAG_DOWN * _thrustMultiplier * deltaTime * up;
_bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_MAG * deltaTime; _bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_SPEED * deltaTime;
_bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_MAG * deltaTime; _bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_SPEED * deltaTime;
getHead()->setPitch(getHead()->getPitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_MAG * deltaTime); getHead()->setPitch(getHead()->getPitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime);
// If thrust keys are being held down, slowly increase thrust to allow reaching great speeds // If thrust keys are being held down, slowly increase thrust to allow reaching great speeds
if (_driveKeys[FWD] || _driveKeys[BACK] || _driveKeys[RIGHT] || _driveKeys[LEFT] || _driveKeys[UP] || _driveKeys[DOWN]) { if (_driveKeys[FWD] || _driveKeys[BACK] || _driveKeys[RIGHT] || _driveKeys[LEFT] || _driveKeys[UP] || _driveKeys[DOWN]) {
@ -1037,7 +1037,7 @@ void MyAvatar::updateChatCircle(float deltaTime) {
const float CIRCLE_INFLUENCE_SCALE = 2.0f; const float CIRCLE_INFLUENCE_SCALE = 2.0f;
const float MIN_RADIUS = 0.3f; const float MIN_RADIUS = 0.3f;
for (int i = sortedAvatars.size() - 1; i >= 0; i--) { for (int i = sortedAvatars.size() - 1; i >= 0; i--) {
float radius = qMax(MIN_RADIUS, (CIRCUMFERENCE_PER_MEMBER * (i + 2)) / PI_TIMES_TWO); float radius = qMax(MIN_RADIUS, (CIRCUMFERENCE_PER_MEMBER * (i + 2)) / TWO_PI);
if (glm::distance(_position, sortedAvatars[i].accumulatedCenter) > radius * CIRCLE_INFLUENCE_SCALE) { if (glm::distance(_position, sortedAvatars[i].accumulatedCenter) > radius * CIRCLE_INFLUENCE_SCALE) {
sortedAvatars.remove(i); sortedAvatars.remove(i);
} else { } else {
@ -1048,7 +1048,7 @@ void MyAvatar::updateChatCircle(float deltaTime) {
return; return;
} }
center = sortedAvatars.last().accumulatedCenter; center = sortedAvatars.last().accumulatedCenter;
float radius = qMax(MIN_RADIUS, (CIRCUMFERENCE_PER_MEMBER * (sortedAvatars.size() + 1)) / PI_TIMES_TWO); float radius = qMax(MIN_RADIUS, (CIRCUMFERENCE_PER_MEMBER * (sortedAvatars.size() + 1)) / TWO_PI);
// compute the average up vector // compute the average up vector
glm::vec3 up = getWorldAlignedOrientation() * IDENTITY_UP; glm::vec3 up = getWorldAlignedOrientation() * IDENTITY_UP;
@ -1069,18 +1069,18 @@ void MyAvatar::updateChatCircle(float deltaTime) {
glm::vec3 delta = _position - center; glm::vec3 delta = _position - center;
glm::vec3 projected = glm::vec3(glm::dot(right, delta), glm::dot(front, delta), 0.0f); glm::vec3 projected = glm::vec3(glm::dot(right, delta), glm::dot(front, delta), 0.0f);
float myAngle = glm::length(projected) > EPSILON ? atan2f(projected.y, projected.x) : 0.0f; float myAngle = glm::length(projected) > EPSILON ? atan2f(projected.y, projected.x) : 0.0f;
float leftDistance = PI_TIMES_TWO; float leftDistance = TWO_PI;
float rightDistance = PI_TIMES_TWO; float rightDistance = TWO_PI;
foreach (const SortedAvatar& sortedAvatar, sortedAvatars) { foreach (const SortedAvatar& sortedAvatar, sortedAvatars) {
delta = sortedAvatar.avatar->getPosition() - center; delta = sortedAvatar.avatar->getPosition() - center;
projected = glm::vec3(glm::dot(right, delta), glm::dot(front, delta), 0.0f); projected = glm::vec3(glm::dot(right, delta), glm::dot(front, delta), 0.0f);
float angle = glm::length(projected) > EPSILON ? atan2f(projected.y, projected.x) : 0.0f; float angle = glm::length(projected) > EPSILON ? atan2f(projected.y, projected.x) : 0.0f;
if (angle < myAngle) { if (angle < myAngle) {
leftDistance = min(myAngle - angle, leftDistance); leftDistance = min(myAngle - angle, leftDistance);
rightDistance = min(PI_TIMES_TWO - (myAngle - angle), rightDistance); rightDistance = min(TWO_PI - (myAngle - angle), rightDistance);
} else { } else {
leftDistance = min(PI_TIMES_TWO - (angle - myAngle), leftDistance); leftDistance = min(TWO_PI - (angle - myAngle), leftDistance);
rightDistance = min(angle - myAngle, rightDistance); rightDistance = min(angle - myAngle, rightDistance);
} }
} }
@ -1126,13 +1126,6 @@ void MyAvatar::setGravity(glm::vec3 gravity) {
} }
} }
void MyAvatar::setOrientation(const glm::quat& orientation) {
glm::vec3 eulerAngles = safeEulerAngles(orientation);
_bodyPitch = eulerAngles.x;
_bodyYaw = eulerAngles.y;
_bodyRoll = eulerAngles.z;
}
void MyAvatar::goHome() { void MyAvatar::goHome() {
qDebug("Going Home!"); qDebug("Going Home!");
setPosition(START_LOCATION); setPosition(START_LOCATION);
@ -1169,7 +1162,7 @@ void MyAvatar::updateLocationInDataServer() {
if (accountManager.isLoggedIn()) { if (accountManager.isLoggedIn()) {
QString positionString(createByteArray(_position)); QString positionString(createByteArray(_position));
QString orientationString(createByteArray(safeEulerAngles(getOrientation()))); QString orientationString(createByteArray(glm::radians(safeEulerAngles(getOrientation()))));
// construct the json to put the user's location // construct the json to put the user's location
QString locationPutJson = QString() + "{\"address\":{\"position\":\"" QString locationPutJson = QString() + "{\"address\":{\"position\":\""
@ -1202,10 +1195,10 @@ void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) {
NodeList::getInstance()->getDomainInfo().setHostname(domainHostnameString); NodeList::getInstance()->getDomainInfo().setHostname(domainHostnameString);
// orient the user to face the target // orient the user to face the target
glm::quat newOrientation = glm::quat(glm::radians(glm::vec3(orientationItems[0].toFloat(), glm::quat newOrientation = glm::quat(glm::vec3(orientationItems[0].toFloat(),
orientationItems[1].toFloat(), orientationItems[1].toFloat(),
orientationItems[2].toFloat()))) orientationItems[2].toFloat()))
* glm::angleAxis(180.0f, glm::vec3(0.0f, 1.0f, 0.0f)); * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
setOrientation(newOrientation); setOrientation(newOrientation);
// move the user a couple units away // move the user a couple units away

View file

@ -44,18 +44,16 @@ public:
void setVelocity(const glm::vec3 velocity) { _velocity = velocity; } void setVelocity(const glm::vec3 velocity) { _velocity = velocity; }
void setLeanScale(float scale) { _leanScale = scale; } void setLeanScale(float scale) { _leanScale = scale; }
void setGravity(glm::vec3 gravity); void setGravity(glm::vec3 gravity);
void setOrientation(const glm::quat& orientation);
void setMoveTarget(const glm::vec3 moveTarget); void setMoveTarget(const glm::vec3 moveTarget);
void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; } void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; }
// getters // getters
float getSpeed() const { return _speed; } float getSpeed() const { return _speed; }
AvatarMode getMode() const { return _mode; } AvatarMode getMode() const { return _mode; }
float getLeanScale() const { return _leanScale; } float getLeanScale() const { return _leanScale; }
float getElapsedTimeStopped() const { return _elapsedTimeStopped; } float getElapsedTimeStopped() const { return _elapsedTimeStopped; }
float getElapsedTimeMoving() const { return _elapsedTimeMoving; } float getElapsedTimeMoving() const { return _elapsedTimeMoving; }
float getAbsoluteHeadYaw() const; float getAbsoluteHeadYaw() const; // degrees
const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; } const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; }
const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; } const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; }
glm::vec3 getGravity() const { return _gravity; } glm::vec3 getGravity() const { return _gravity; }
@ -68,7 +66,7 @@ public:
// Set what driving keys are being pressed to control thrust levels // Set what driving keys are being pressed to control thrust levels
void setDriveKeys(int key, float val) { _driveKeys[key] = val; }; void setDriveKeys(int key, float val) { _driveKeys[key] = val; };
bool getDriveKeys(int key) { return _driveKeys[key]; }; bool getDriveKeys(int key) { return _driveKeys[key] != 0.f; };
void jump() { _shouldJump = true; }; void jump() { _shouldJump = true; };
bool isMyAvatar() { return true; } bool isMyAvatar() { return true; }
@ -101,8 +99,8 @@ public slots:
private: private:
bool _mousePressed; bool _mousePressed;
float _bodyPitchDelta; float _bodyPitchDelta; // degrees
float _bodyRollDelta; float _bodyRollDelta; // degrees
bool _shouldJump; bool _shouldJump;
float _driveKeys[MAX_DRIVE_KEYS]; float _driveKeys[MAX_DRIVE_KEYS];
glm::vec3 _gravity; glm::vec3 _gravity;

View file

@ -24,7 +24,7 @@ void SkeletonModel::simulate(float deltaTime, bool delayLoad) {
return; return;
} }
setTranslation(_owningAvatar->getPosition()); setTranslation(_owningAvatar->getPosition());
setRotation(_owningAvatar->getOrientation() * glm::angleAxis(180.0f, glm::vec3(0.0f, 1.0f, 0.0f))); setRotation(_owningAvatar->getOrientation() * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)));
const float MODEL_SCALE = 0.0006f; const float MODEL_SCALE = 0.0006f;
setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale() * MODEL_SCALE); setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale() * MODEL_SCALE);
@ -199,8 +199,9 @@ void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const
glm::mat3 axes = glm::mat3_cast(_rotation); glm::mat3 axes = glm::mat3_cast(_rotation);
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) * glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) *
joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation))); joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation)));
state.rotation = glm::angleAxis(-_owningAvatar->getHead()->getLeanSideways(), glm::normalize(inverse * axes[2])) * state.rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getLeanSideways(),
glm::angleAxis(-_owningAvatar->getHead()->getLeanForward(), glm::normalize(inverse * axes[0])) * joint.rotation; glm::normalize(inverse * axes[2])) * glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getLeanForward(),
glm::normalize(inverse * axes[0])) * joint.rotation;
} }
void SkeletonModel::stretchArm(int jointIndex, const glm::vec3& position) { void SkeletonModel::stretchArm(int jointIndex, const glm::vec3& position) {

View file

@ -65,8 +65,8 @@ void Faceshift::update() {
return; return;
} }
// get the euler angles relative to the window // get the euler angles relative to the window
glm::vec3 eulers = safeEulerAngles(_headRotation * glm::quat(glm::radians(glm::vec3( glm::vec3 eulers = glm::degrees(safeEulerAngles(_headRotation * glm::quat(glm::radians(glm::vec3(
(_eyeGazeLeftPitch + _eyeGazeRightPitch) / 2.0f, (_eyeGazeLeftYaw + _eyeGazeRightYaw) / 2.0f, 0.0f)))); (_eyeGazeLeftPitch + _eyeGazeRightPitch) / 2.0f, (_eyeGazeLeftYaw + _eyeGazeRightYaw) / 2.0f, 0.0f)))));
// compute and subtract the long term average // compute and subtract the long term average
const float LONG_TERM_AVERAGE_SMOOTHING = 0.999f; const float LONG_TERM_AVERAGE_SMOOTHING = 0.999f;

View file

@ -33,6 +33,7 @@ public:
const glm::vec3& getHeadAngularVelocity() const { return _headAngularVelocity; } const glm::vec3& getHeadAngularVelocity() const { return _headAngularVelocity; }
const glm::vec3& getHeadTranslation() const { return _headTranslation; } const glm::vec3& getHeadTranslation() const { return _headTranslation; }
// these pitch/yaw angles are in degrees
float getEyeGazeLeftPitch() const { return _eyeGazeLeftPitch; } float getEyeGazeLeftPitch() const { return _eyeGazeLeftPitch; }
float getEyeGazeLeftYaw() const { return _eyeGazeLeftYaw; } float getEyeGazeLeftYaw() const { return _eyeGazeLeftYaw; }
@ -96,9 +97,9 @@ private:
glm::vec3 _headAngularVelocity; glm::vec3 _headAngularVelocity;
glm::vec3 _headTranslation; glm::vec3 _headTranslation;
// degrees
float _eyeGazeLeftPitch; float _eyeGazeLeftPitch;
float _eyeGazeLeftYaw; float _eyeGazeLeftYaw;
float _eyeGazeRightPitch; float _eyeGazeRightPitch;
float _eyeGazeRightYaw; float _eyeGazeRightYaw;
@ -121,10 +122,12 @@ private:
int _jawOpenIndex; int _jawOpenIndex;
// degrees
float _longTermAverageEyePitch; float _longTermAverageEyePitch;
float _longTermAverageEyeYaw; float _longTermAverageEyeYaw;
bool _longTermAverageInitialized; bool _longTermAverageInitialized;
// degrees
float _estimatedEyePitch; float _estimatedEyePitch;
float _estimatedEyeYaw; float _estimatedEyeYaw;
}; };

View file

@ -27,7 +27,7 @@ int OculusManager::_scaleLocation;
int OculusManager::_scaleInLocation; int OculusManager::_scaleInLocation;
int OculusManager::_hmdWarpParamLocation; int OculusManager::_hmdWarpParamLocation;
bool OculusManager::_isConnected = false; bool OculusManager::_isConnected = false;
float OculusManager::_yawOffset = 0; float OculusManager::_yawOffset = 0.0f; // radians
#ifdef HAVE_LIBOVR #ifdef HAVE_LIBOVR
using namespace OVR; using namespace OVR;
@ -198,12 +198,7 @@ void OculusManager::updateYawOffset() {
void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) { void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) {
#ifdef HAVE_LIBOVR #ifdef HAVE_LIBOVR
_sensorFusion->GetOrientation().GetEulerAngles<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&yaw, &pitch, &roll); _sensorFusion->GetOrientation().GetEulerAngles<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&yaw, &pitch, &roll);
yaw = yaw - _yawOffset;
// convert each angle to degrees
// remove the yaw offset from the returned yaw
yaw = glm::degrees(yaw - _yawOffset);
pitch = glm::degrees(pitch);
roll = glm::degrees(roll);
#endif #endif
} }

View file

@ -32,6 +32,9 @@ public:
static void reset(); static void reset();
/// param \yaw[out] yaw in radians
/// param \pitch[out] pitch in radians
/// param \roll[out] roll in radians
static void getEulerAngles(float& yaw, float& pitch, float& roll); static void getEulerAngles(float& yaw, float& pitch, float& roll);
static void updateYawOffset(); static void updateYawOffset();

View file

@ -89,7 +89,7 @@ void SixenseManager::update(float deltaTime) {
// Rotation of Palm // Rotation of Palm
glm::quat rotation(data.rot_quat[3], -data.rot_quat[0], data.rot_quat[1], -data.rot_quat[2]); glm::quat rotation(data.rot_quat[3], -data.rot_quat[0], data.rot_quat[1], -data.rot_quat[2]);
rotation = glm::angleAxis(180.0f, glm::vec3(0.f, 1.f, 0.f)) * rotation; rotation = glm::angleAxis(PI, glm::vec3(0.f, 1.f, 0.f)) * rotation;
const glm::vec3 PALM_VECTOR(0.0f, -1.0f, 0.0f); const glm::vec3 PALM_VECTOR(0.0f, -1.0f, 0.0f);
glm::vec3 newNormal = rotation * PALM_VECTOR; glm::vec3 newNormal = rotation * PALM_VECTOR;
palm->setRawNormal(newNormal); palm->setRawNormal(newNormal);

View file

@ -52,7 +52,7 @@ void TV3DManager::setFrustum(Camera& whichCamera) {
double nearZ = whichCamera.getNearClip(); // near clipping plane double nearZ = whichCamera.getNearClip(); // near clipping plane
double screenZ = Application::getInstance()->getViewFrustum()->getFocalLength(); // screen projection plane double screenZ = Application::getInstance()->getViewFrustum()->getFocalLength(); // screen projection plane
double top = nearZ * tan(DTR * fovy / 2); //sets top of frustum based on fovy and near clipping plane double top = nearZ * tan(DTR * fovy / 2.0); //sets top of frustum based on fovy and near clipping plane
double right = _aspect * top; // sets right of frustum based on aspect ratio double right = _aspect * top; // sets right of frustum based on aspect ratio
double frustumshift = (IOD / 2) * nearZ / screenZ; double frustumshift = (IOD / 2) * nearZ / screenZ;

View file

@ -533,8 +533,8 @@ public:
glm::quat postRotation; glm::quat postRotation;
glm::mat4 postTransform; glm::mat4 postTransform;
glm::vec3 rotationMin; glm::vec3 rotationMin; // radians
glm::vec3 rotationMax; glm::vec3 rotationMax; // radians
}; };
glm::mat4 getGlobalTransform(const QMultiHash<QString, QString>& parentMap, glm::mat4 getGlobalTransform(const QMultiHash<QString, QString>& parentMap,
@ -806,7 +806,7 @@ void setTangents(FBXMesh& mesh, int firstIndex, int secondIndex) {
} }
glm::vec2 texCoordDelta = mesh.texCoords.at(secondIndex) - mesh.texCoords.at(firstIndex); glm::vec2 texCoordDelta = mesh.texCoords.at(secondIndex) - mesh.texCoords.at(firstIndex);
mesh.tangents[firstIndex] += glm::cross(glm::angleAxis( mesh.tangents[firstIndex] += glm::cross(glm::angleAxis(
-glm::degrees(atan2f(-texCoordDelta.t, texCoordDelta.s)), normal) * glm::normalize(bitangent), normal); - atan2f(-texCoordDelta.t, texCoordDelta.s), normal) * glm::normalize(bitangent), normal);
} }
QVector<int> getIndices(const QVector<QString> ids, QVector<QString> modelIDs) { QVector<int> getIndices(const QVector<QString> ids, QVector<QString> modelIDs) {
@ -1000,6 +1000,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
jointRightFingertipIDs[index] = getID(object.properties); jointRightFingertipIDs[index] = getID(object.properties);
} }
glm::vec3 translation; glm::vec3 translation;
// NOTE: the euler angles as supplied by the FBX file are in degrees
glm::vec3 rotationOffset; glm::vec3 rotationOffset;
glm::vec3 preRotation, rotation, postRotation; glm::vec3 preRotation, rotation, postRotation;
glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f); glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f);
@ -1054,7 +1055,9 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
} else if (property.properties.at(0) == "RotationMin") { } else if (property.properties.at(0) == "RotationMin") {
rotationMin = getVec3(property.properties, index); rotationMin = getVec3(property.properties, index);
} else if (property.properties.at(0) == "RotationMax") { }
// NOTE: these rotation limits are stored in degrees (NOT radians)
else if (property.properties.at(0) == "RotationMax") {
rotationMax = getVec3(property.properties, index); rotationMax = getVec3(property.properties, index);
} else if (property.properties.at(0) == "RotationMinX") { } else if (property.properties.at(0) == "RotationMinX") {
@ -1104,10 +1107,12 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
model.postRotation = glm::quat(glm::radians(postRotation)); model.postRotation = glm::quat(glm::radians(postRotation));
model.postTransform = glm::translate(-rotationPivot) * glm::translate(scalePivot) * model.postTransform = glm::translate(-rotationPivot) * glm::translate(scalePivot) *
glm::scale(scale) * glm::translate(-scalePivot); glm::scale(scale) * glm::translate(-scalePivot);
model.rotationMin = glm::vec3(rotationMinX ? rotationMin.x : -180.0f, // NOTE: anbgles from the FBX file are in degrees
rotationMinY ? rotationMin.y : -180.0f, rotationMinZ ? rotationMin.z : -180.0f); // so we convert them to radians for the FBXModel class
model.rotationMax = glm::vec3(rotationMaxX ? rotationMax.x : 180.0f, model.rotationMin = glm::radians(glm::vec3(rotationMinX ? rotationMin.x : -180.0f,
rotationMaxY ? rotationMax.y : 180.0f, rotationMaxZ ? rotationMax.z : 180.0f); rotationMinY ? rotationMin.y : -180.0f, rotationMinZ ? rotationMin.z : -180.0f));
model.rotationMax = glm::radians(glm::vec3(rotationMaxX ? rotationMax.x : 180.0f,
rotationMaxY ? rotationMax.y : 180.0f, rotationMaxZ ? rotationMax.z : 180.0f));
models.insert(getID(object.properties), model); models.insert(getID(object.properties), model);
} else if (object.name == "Texture") { } else if (object.name == "Texture") {

View file

@ -76,8 +76,8 @@ public:
glm::quat postRotation; glm::quat postRotation;
glm::mat4 postTransform; glm::mat4 postTransform;
glm::mat4 transform; glm::mat4 transform;
glm::vec3 rotationMin; glm::vec3 rotationMin; // radians
glm::vec3 rotationMax; glm::vec3 rotationMax; // radians
glm::quat inverseDefaultRotation; glm::quat inverseDefaultRotation;
glm::quat inverseBindRotation; glm::quat inverseBindRotation;
glm::mat4 bindTransform; glm::mat4 bindTransform;

View file

@ -30,11 +30,11 @@ void GeometryCache::renderHemisphere(int slices, int stacks) {
GLfloat* vertexData = new GLfloat[vertices * 3]; GLfloat* vertexData = new GLfloat[vertices * 3];
GLfloat* vertex = vertexData; GLfloat* vertex = vertexData;
for (int i = 0; i < stacks - 1; i++) { for (int i = 0; i < stacks - 1; i++) {
float phi = PIf * 0.5f * i / (stacks - 1); float phi = PI_OVER_TWO * float(i) / float(stacks - 1);
float z = sinf(phi), radius = cosf(phi); float z = sinf(phi), radius = cosf(phi);
for (int j = 0; j < slices; j++) { for (int j = 0; j < slices; j++) {
float theta = PIf * 2.0f * j / slices; float theta = TWO_PI * float(j) / float(slices);
*(vertex++) = sinf(theta) * radius; *(vertex++) = sinf(theta) * radius;
*(vertex++) = cosf(theta) * radius; *(vertex++) = cosf(theta) * radius;
@ -180,7 +180,7 @@ void GeometryCache::renderHalfCylinder(int slices, int stacks) {
float y = (float)i / (stacks - 1); float y = (float)i / (stacks - 1);
for (int j = 0; j <= slices; j++) { for (int j = 0; j <= slices; j++) {
float theta = 3 * PIf / 2 + PIf * j / slices; float theta = 3.f * PI_OVER_TWO + PI * float(j) / float(slices);
//normals //normals
*(vertex++) = sinf(theta); *(vertex++) = sinf(theta);

View file

@ -760,15 +760,15 @@ float Model::getLimbLength(int jointIndex) const {
void Model::applyRotationDelta(int jointIndex, const glm::quat& delta, bool constrain) { void Model::applyRotationDelta(int jointIndex, const glm::quat& delta, bool constrain) {
JointState& state = _jointStates[jointIndex]; JointState& state = _jointStates[jointIndex];
const FBXJoint& joint = _geometry->getFBXGeometry().joints[jointIndex]; const FBXJoint& joint = _geometry->getFBXGeometry().joints[jointIndex];
if (!constrain || (joint.rotationMin == glm::vec3(-180.0f, -180.0f, -180.0f) && if (!constrain || (joint.rotationMin == glm::vec3(-PI, -PI, -PI) &&
joint.rotationMax == glm::vec3(180.0f, 180.0f, 180.0f))) { joint.rotationMax == glm::vec3(PI, PI, PI))) {
// no constraints // no constraints
state.rotation = state.rotation * glm::inverse(state.combinedRotation) * delta * state.combinedRotation; state.rotation = state.rotation * glm::inverse(state.combinedRotation) * delta * state.combinedRotation;
state.combinedRotation = delta * state.combinedRotation; state.combinedRotation = delta * state.combinedRotation;
return; return;
} }
glm::quat newRotation = glm::quat(glm::radians(glm::clamp(safeEulerAngles(state.rotation * glm::quat newRotation = glm::quat(glm::clamp(safeEulerAngles(state.rotation *
glm::inverse(state.combinedRotation) * delta * state.combinedRotation), joint.rotationMin, joint.rotationMax))); glm::inverse(state.combinedRotation) * delta * state.combinedRotation), joint.rotationMin, joint.rotationMax));
state.combinedRotation = state.combinedRotation * glm::inverse(state.rotation) * newRotation; state.combinedRotation = state.combinedRotation * glm::inverse(state.rotation) * newRotation;
state.rotation = newRotation; state.rotation = newRotation;
} }
@ -789,7 +789,7 @@ void Model::renderCollisionProxies(float alpha) {
glTranslatef(position.x, position.y, position.z); glTranslatef(position.x, position.y, position.z);
const glm::quat& rotation = shape->getRotation(); const glm::quat& rotation = shape->getRotation();
glm::vec3 axis = glm::axis(rotation); glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
// draw a grey sphere at shape position // draw a grey sphere at shape position
glColor4f(0.75f, 0.75f, 0.75f, alpha); glColor4f(0.75f, 0.75f, 0.75f, alpha);
@ -864,7 +864,7 @@ void Model::applyCollision(CollisionInfo& collision) {
axis = glm::normalize(axis); axis = glm::normalize(axis);
glm::vec3 end; glm::vec3 end;
getJointPosition(jointIndex, end); getJointPosition(jointIndex, end);
glm::vec3 newEnd = start + glm::angleAxis(glm::degrees(angle), axis) * (end - start); glm::vec3 newEnd = start + glm::angleAxis(angle, axis) * (end - start);
// try to move it // try to move it
setJointPosition(jointIndex, newEnd, -1, true); setJointPosition(jointIndex, newEnd, -1, true);
} }

View file

@ -16,6 +16,7 @@
using namespace starfield; using namespace starfield;
const float Generator::STAR_COLORIZATION = 0.1f; const float Generator::STAR_COLORIZATION = 0.1f;
const float PI_OVER_180 = 3.14159265358979f / 180.f;
void Generator::computeStarPositions(InputVertices& destination, unsigned limit, unsigned seed) { void Generator::computeStarPositions(InputVertices& destination, unsigned limit, unsigned seed) {
InputVertices* vertices = & destination; InputVertices* vertices = & destination;

View file

@ -138,11 +138,11 @@ glm::quat MetavoxelEditor::getGridRotation() const {
return glm::quat(); return glm::quat();
case GRID_PLANE_XZ: case GRID_PLANE_XZ:
return glm::angleAxis(-90.0f, glm::vec3(1.0f, 0.0f, 0.0f)); return glm::angleAxis(-PI_OVER_TWO, glm::vec3(1.0f, 0.0f, 0.0f));
case GRID_PLANE_YZ: case GRID_PLANE_YZ:
default: default:
return glm::angleAxis(90.0f, glm::vec3(0.0f, 1.0f, 0.0f)); return glm::angleAxis(PI_OVER_TWO, glm::vec3(0.0f, 1.0f, 0.0f));
} }
} }
@ -275,7 +275,7 @@ void MetavoxelEditor::render() {
glm::quat rotation = getGridRotation(); glm::quat rotation = getGridRotation();
glm::vec3 axis = glm::axis(rotation); glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
MetavoxelTool* tool = getActiveTool(); MetavoxelTool* tool = getActiveTool();
if (tool) { if (tool) {

View file

@ -9,10 +9,6 @@
#ifndef __interface__world__ #ifndef __interface__world__
#define __interface__world__ #define __interface__world__
#ifndef PIf
#define PIf 3.14159265f
#endif
const float GRAVITY_EARTH = 9.80665f; const float GRAVITY_EARTH = 9.80665f;
const float EDGE_SIZE_GROUND_PLANE = 20.f; const float EDGE_SIZE_GROUND_PLANE = 20.f;

View file

@ -41,7 +41,7 @@ Sound::Sound(float volume, float frequency, float duration, float decay, QObject
int numSamples = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; // we add sounds in chunks of this many samples int numSamples = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; // we add sounds in chunks of this many samples
int chunkStartingSample = 0; int chunkStartingSample = 0;
float waveFrequency = (frequency / SAMPLE_RATE) * PI_TIMES_TWO; float waveFrequency = (frequency / SAMPLE_RATE) * TWO_PI;
while (volume > 0.f) { while (volume > 0.f) {
for (int i = 0; i < numSamples; i++) { for (int i = 0; i < numSamples; i++) {
t = (float)chunkStartingSample + (float)i; t = (float)chunkStartingSample + (float)i;

View file

@ -33,9 +33,9 @@ QNetworkAccessManager* AvatarData::networkAccessManager = NULL;
AvatarData::AvatarData() : AvatarData::AvatarData() :
NodeData(), NodeData(),
_handPosition(0,0,0), _handPosition(0,0,0),
_bodyYaw(-90.0), _bodyYaw(-90.f),
_bodyPitch(0.0), _bodyPitch(0.0f),
_bodyRoll(0.0), _bodyRoll(0.0f),
_targetScale(1.0f), _targetScale(1.0f),
_handState(0), _handState(0),
_keyState(NO_KEY_DOWN), _keyState(NO_KEY_DOWN),
@ -510,7 +510,7 @@ void AvatarData::setClampedTargetScale(float targetScale) {
} }
void AvatarData::setOrientation(const glm::quat& orientation) { void AvatarData::setOrientation(const glm::quat& orientation) {
glm::vec3 eulerAngles = safeEulerAngles(orientation); glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(orientation));
_bodyPitch = eulerAngles.x; _bodyPitch = eulerAngles.x;
_bodyYaw = eulerAngles.y; _bodyYaw = eulerAngles.y;
_bodyRoll = eulerAngles.z; _bodyRoll = eulerAngles.z;

View file

@ -108,7 +108,7 @@ public:
QByteArray toByteArray(); QByteArray toByteArray();
int parseData(const QByteArray& packet); int parseData(const QByteArray& packet);
// Body Rotation // Body Rotation (degrees)
float getBodyYaw() const { return _bodyYaw; } float getBodyYaw() const { return _bodyYaw; }
void setBodyYaw(float bodyYaw) { _bodyYaw = bodyYaw; } void setBodyYaw(float bodyYaw) { _bodyYaw = bodyYaw; }
float getBodyPitch() const { return _bodyPitch; } float getBodyPitch() const { return _bodyPitch; }
@ -122,7 +122,7 @@ public:
glm::quat getHeadOrientation() const { return _headData->getOrientation(); } glm::quat getHeadOrientation() const { return _headData->getOrientation(); }
void setHeadOrientation(const glm::quat& orientation) { _headData->setOrientation(orientation); } void setHeadOrientation(const glm::quat& orientation) { _headData->setOrientation(orientation); }
// access to Head().set/getMousePitch // access to Head().set/getMousePitch (degrees)
float getHeadPitch() const { return _headData->getPitch(); } float getHeadPitch() const { return _headData->getPitch(); }
void setHeadPitch(float value) { _headData->setPitch(value); }; void setHeadPitch(float value) { _headData->setPitch(value); };
@ -217,9 +217,9 @@ protected:
glm::vec3 _handPosition; glm::vec3 _handPosition;
// Body rotation // Body rotation
float _bodyYaw; float _bodyYaw; // degrees
float _bodyPitch; float _bodyPitch; // degrees
float _bodyRoll; float _bodyRoll; // degrees
// Body scale // Body scale
float _targetScale; float _targetScale;

View file

@ -17,9 +17,9 @@ HeadData::HeadData(AvatarData* owningAvatar) :
_yaw(0.0f), _yaw(0.0f),
_pitch(0.0f), _pitch(0.0f),
_roll(0.0f), _roll(0.0f),
_lookAtPosition(0.0f, 0.0f, 0.0f),
_leanSideways(0.0f), _leanSideways(0.0f),
_leanForward(0.0f), _leanForward(0.0f),
_lookAtPosition(0.0f, 0.0f, 0.0f),
_audioLoudness(0.0f), _audioLoudness(0.0f),
_isFaceshiftConnected(false), _isFaceshiftConnected(false),
_leftEyeBlink(0.0f), _leftEyeBlink(0.0f),
@ -39,12 +39,11 @@ void HeadData::setOrientation(const glm::quat& orientation) {
// rotate body about vertical axis // rotate body about vertical axis
glm::quat bodyOrientation = _owningAvatar->getOrientation(); glm::quat bodyOrientation = _owningAvatar->getOrientation();
glm::vec3 newFront = glm::inverse(bodyOrientation) * (orientation * IDENTITY_FRONT); glm::vec3 newFront = glm::inverse(bodyOrientation) * (orientation * IDENTITY_FRONT);
bodyOrientation = bodyOrientation * glm::angleAxis(glm::degrees(atan2f(-newFront.x, -newFront.z)), bodyOrientation = bodyOrientation * glm::angleAxis(atan2f(-newFront.x, -newFront.z), glm::vec3(0.0f, 1.0f, 0.0f));
glm::vec3(0.0f, 1.0f, 0.0f));
_owningAvatar->setOrientation(bodyOrientation); _owningAvatar->setOrientation(bodyOrientation);
// the rest goes to the head // the rest goes to the head
glm::vec3 eulers = safeEulerAngles(glm::inverse(bodyOrientation) * orientation); glm::vec3 eulers = DEGREES_PER_RADIAN * safeEulerAngles(glm::inverse(bodyOrientation) * orientation);
_pitch = eulers.x; _pitch = eulers.x;
_yaw = eulers.y; _yaw = eulers.y;
_roll = eulers.z; _roll = eulers.z;

View file

@ -15,12 +15,13 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
const float MIN_HEAD_YAW = -110; // degrees
const float MAX_HEAD_YAW = 110; const float MIN_HEAD_YAW = -110.f;
const float MIN_HEAD_PITCH = -60; const float MAX_HEAD_YAW = 110.f;
const float MAX_HEAD_PITCH = 60; const float MIN_HEAD_PITCH = -60.f;
const float MIN_HEAD_ROLL = -50; const float MAX_HEAD_PITCH = 60.f;
const float MAX_HEAD_ROLL = 50; const float MIN_HEAD_ROLL = -50.f;
const float MAX_HEAD_ROLL = 50.f;
class AvatarData; class AvatarData;
@ -29,21 +30,17 @@ public:
HeadData(AvatarData* owningAvatar); HeadData(AvatarData* owningAvatar);
virtual ~HeadData() { }; virtual ~HeadData() { };
// degrees
float getLeanSideways() const { return _leanSideways; } float getLeanSideways() const { return _leanSideways; }
void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; } void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; }
float getLeanForward() const { return _leanForward; } float getLeanForward() const { return _leanForward; }
void setLeanForward(float leanForward) { _leanForward = leanForward; } void setLeanForward(float leanForward) { _leanForward = leanForward; }
float getYaw() const { return _yaw; } float getYaw() const { return _yaw; }
void setYaw(float yaw) { _yaw = glm::clamp(yaw, MIN_HEAD_YAW, MAX_HEAD_YAW); } void setYaw(float yaw) { _yaw = glm::clamp(yaw, MIN_HEAD_YAW, MAX_HEAD_YAW); }
float getPitch() const { return _pitch; } float getPitch() const { return _pitch; }
void setPitch(float pitch) { _pitch = glm::clamp(pitch, MIN_HEAD_PITCH, MAX_HEAD_PITCH); } void setPitch(float pitch) { _pitch = glm::clamp(pitch, MIN_HEAD_PITCH, MAX_HEAD_PITCH); }
float getRoll() const { return _roll; } float getRoll() const { return _roll; }
void setRoll(float roll) { _roll = glm::clamp(roll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } void setRoll(float roll) { _roll = glm::clamp(roll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); }
virtual float getTweakedYaw() const { return _yaw; } virtual float getTweakedYaw() const { return _yaw; }
virtual float getTweakedPitch() const { return _pitch; } virtual float getTweakedPitch() const { return _pitch; }
virtual float getTweakedRoll() const { return _roll; } virtual float getTweakedRoll() const { return _roll; }
@ -62,6 +59,7 @@ public:
float getPupilDilation() const { return _pupilDilation; } float getPupilDilation() const { return _pupilDilation; }
void setPupilDilation(float pupilDilation) { _pupilDilation = pupilDilation; } void setPupilDilation(float pupilDilation) { _pupilDilation = pupilDilation; }
// degrees
void addYaw(float yaw); void addYaw(float yaw);
void addPitch(float pitch); void addPitch(float pitch);
void addRoll(float roll); void addRoll(float roll);
@ -73,12 +71,14 @@ public:
friend class AvatarData; friend class AvatarData;
protected: protected:
// degrees
float _yaw; float _yaw;
float _pitch; float _pitch;
float _roll; float _roll;
glm::vec3 _lookAtPosition;
float _leanSideways; float _leanSideways;
float _leanForward; float _leanForward;
glm::vec3 _lookAtPosition;
float _audioLoudness; float _audioLoudness;
bool _isFaceshiftConnected; bool _isFaceshiftConnected;
float _leftEyeBlink; float _leftEyeBlink;

View file

@ -363,7 +363,7 @@ signals:
private: private:
glm::vec3 _translation; glm::vec3 _translation;
glm::vec3 _rotation; glm::vec3 _rotation; // Euler Angles in degrees
float _scale; float _scale;
}; };

View file

@ -384,14 +384,14 @@ bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const
// Compute the angular distance between the two orientations // Compute the angular distance between the two orientations
const float ORIENTATION_SIMILAR_ENOUGH = 10.0f; // 10 degrees in any direction const float ORIENTATION_SIMILAR_ENOUGH = 10.0f; // 10 degrees in any direction
glm::quat dQOrientation = _orientation * glm::inverse(compareTo._orientation); glm::quat dQOrientation = _orientation * glm::inverse(compareTo._orientation);
float angleOrientation = compareTo._orientation == _orientation ? 0.0f : glm::angle(dQOrientation); float angleOrientation = compareTo._orientation == _orientation ? 0.0f : glm::degrees(glm::angle(dQOrientation));
if (isNaN(angleOrientation)) { if (isNaN(angleOrientation)) {
angleOrientation = 0.0f; angleOrientation = 0.0f;
} }
glm::quat dQEyeOffsetOrientation = _eyeOffsetOrientation * glm::inverse(compareTo._eyeOffsetOrientation); glm::quat dQEyeOffsetOrientation = _eyeOffsetOrientation * glm::inverse(compareTo._eyeOffsetOrientation);
float angleEyeOffsetOrientation = compareTo._eyeOffsetOrientation == _eyeOffsetOrientation float angleEyeOffsetOrientation = compareTo._eyeOffsetOrientation == _eyeOffsetOrientation
? 0.0f : glm::angle(dQEyeOffsetOrientation); ? 0.0f : glm::degrees(glm::angle(dQEyeOffsetOrientation));
if (isNaN(angleEyeOffsetOrientation)) { if (isNaN(angleEyeOffsetOrientation)) {
angleOrientation = 0.0f; angleOrientation = 0.0f;
} }
@ -463,7 +463,7 @@ void ViewFrustum::computePickRay(float x, float y, glm::vec3& origin, glm::vec3&
void ViewFrustum::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearValue, float& farValue, void ViewFrustum::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearValue, float& farValue,
glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const { glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const {
// compute our dimensions the usual way // compute our dimensions the usual way
float hheight = _nearClip * tanf(_fieldOfView * 0.5f * PI_OVER_180); float hheight = _nearClip * tanf(_fieldOfView * 0.5f * RADIANS_PER_DEGREE);
float hwidth = _aspectRatio * hheight; float hwidth = _aspectRatio * hheight;
// get our frustum corners in view space // get our frustum corners in view space

View file

@ -120,7 +120,7 @@ private:
glm::vec3 _right; glm::vec3 _right;
// Lens attributes // Lens attributes
float _fieldOfView; float _fieldOfView; // degrees
float _aspectRatio; float _aspectRatio;
float _nearClip; float _nearClip;
float _farClip; float _farClip;

View file

@ -387,11 +387,10 @@ TouchEvent::TouchEvent(const QTouchEvent& event, const TouchEvent& other) {
calculateMetaAttributes(other); calculateMetaAttributes(other);
} }
// returns the degrees between two points (note: 0 degrees is 'east') // returns the angle (in degrees) between two points (note: 0 degrees is 'east')
float angleBetweenPoints(const glm::vec2& a, const glm::vec2& b ) { float angleBetweenPoints(const glm::vec2& a, const glm::vec2& b ) {
glm::vec2 length = b - a; glm::vec2 length = b - a;
float radian = std::atan2(length.y, length.x); float angle = DEGREES_PER_RADIAN * std::atan2(length.y, length.x);
float angle = radian * 180.0f / PIE;
if (angle < 0) { if (angle < 0) {
angle += 360.0f; angle += 360.0f;
}; };

View file

@ -74,6 +74,8 @@ public:
float radius; float radius;
bool isPinching; bool isPinching;
bool isPinchOpening; bool isPinchOpening;
// angles are in degrees
QVector<float> angles; // angle from center to each point QVector<float> angles; // angle from center to each point
float angle; // the average of the angles float angle; // the average of the angles
float deltaAngle; // the change in average angle from last event float deltaAngle; // the change in average angle from last event

View file

@ -22,8 +22,8 @@ glm::quat Quat::multiply(const glm::quat& q1, const glm::quat& q2) {
return q1 * q2; return q1 * q2;
} }
glm::quat Quat::fromVec3(const glm::vec3& vec3) { glm::quat Quat::fromVec3(const glm::vec3& eulerAngles) {
return glm::quat(vec3); return glm::quat(glm::radians(eulerAngles));
} }
glm::quat Quat::fromPitchYawRoll(float pitch, float yaw, float roll) { glm::quat Quat::fromPitchYawRoll(float pitch, float yaw, float roll) {
@ -47,11 +47,11 @@ glm::vec3 Quat::getUp(const glm::quat& orientation) {
} }
glm::vec3 Quat::safeEulerAngles(const glm::quat& orientation) { glm::vec3 Quat::safeEulerAngles(const glm::quat& orientation) {
return ::safeEulerAngles(orientation); return glm::degrees(::safeEulerAngles(orientation));
} }
glm::quat Quat::angleAxis(float angle, const glm::vec3& v) { glm::quat Quat::angleAxis(float angle, const glm::vec3& v) {
return glm::angleAxis(angle, v); return glm::angleAxis(glm::radians(angle), v);
} }
glm::quat Quat::mix(const glm::quat& q1, const glm::quat& q2, float alpha) { glm::quat Quat::mix(const glm::quat& q1, const glm::quat& q2, float alpha) {

View file

@ -24,13 +24,13 @@ class Quat : public QObject {
public slots: public slots:
glm::quat multiply(const glm::quat& q1, const glm::quat& q2); glm::quat multiply(const glm::quat& q1, const glm::quat& q2);
glm::quat fromVec3(const glm::vec3& vec3); glm::quat fromVec3(const glm::vec3& vec3);
glm::quat fromPitchYawRoll(float pitch, float yaw, float roll); glm::quat fromPitchYawRoll(float pitch, float yaw, float roll); // degrees
glm::quat inverse(const glm::quat& q); glm::quat inverse(const glm::quat& q);
glm::vec3 getFront(const glm::quat& orientation); glm::vec3 getFront(const glm::quat& orientation);
glm::vec3 getRight(const glm::quat& orientation); glm::vec3 getRight(const glm::quat& orientation);
glm::vec3 getUp(const glm::quat& orientation); glm::vec3 getUp(const glm::quat& orientation);
glm::vec3 safeEulerAngles(const glm::quat& orientation); glm::vec3 safeEulerAngles(const glm::quat& orientation); // degrees
glm::quat angleAxis(float angle, const glm::vec3& v); glm::quat angleAxis(float angle, const glm::vec3& v); // degrees
glm::quat mix(const glm::quat& q1, const glm::quat& q2, float alpha); glm::quat mix(const glm::quat& q1, const glm::quat& q2, float alpha);
void print(const QString& lable, const glm::quat& q); void print(const QString& lable, const glm::quat& q);
}; };

View file

@ -501,27 +501,27 @@ int unpackFloatVec3FromSignedTwoByteFixed(const unsigned char* sourceBuffer, glm
} }
int packFloatAngleToTwoByte(unsigned char* buffer, float angle) { int packFloatAngleToTwoByte(unsigned char* buffer, float degrees) {
const float ANGLE_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 360.0); const float ANGLE_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 360.f);
uint16_t angleHolder = floorf((angle + 180) * ANGLE_CONVERSION_RATIO); uint16_t angleHolder = floorf((degrees + 180.f) * ANGLE_CONVERSION_RATIO);
memcpy(buffer, &angleHolder, sizeof(uint16_t)); memcpy(buffer, &angleHolder, sizeof(uint16_t));
return sizeof(uint16_t); return sizeof(uint16_t);
} }
int unpackFloatAngleFromTwoByte(const uint16_t* byteAnglePointer, float* destinationPointer) { int unpackFloatAngleFromTwoByte(const uint16_t* byteAnglePointer, float* destinationPointer) {
*destinationPointer = (*byteAnglePointer / (float) std::numeric_limits<uint16_t>::max()) * 360.0 - 180; *destinationPointer = (*byteAnglePointer / (float) std::numeric_limits<uint16_t>::max()) * 360.f - 180.f;
return sizeof(uint16_t); return sizeof(uint16_t);
} }
int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput) { int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput) {
const float QUAT_PART_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 2.0); const float QUAT_PART_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 2.f);
uint16_t quatParts[4]; uint16_t quatParts[4];
quatParts[0] = floorf((quatInput.x + 1.0) * QUAT_PART_CONVERSION_RATIO); quatParts[0] = floorf((quatInput.x + 1.f) * QUAT_PART_CONVERSION_RATIO);
quatParts[1] = floorf((quatInput.y + 1.0) * QUAT_PART_CONVERSION_RATIO); quatParts[1] = floorf((quatInput.y + 1.f) * QUAT_PART_CONVERSION_RATIO);
quatParts[2] = floorf((quatInput.z + 1.0) * QUAT_PART_CONVERSION_RATIO); quatParts[2] = floorf((quatInput.z + 1.f) * QUAT_PART_CONVERSION_RATIO);
quatParts[3] = floorf((quatInput.w + 1.0) * QUAT_PART_CONVERSION_RATIO); quatParts[3] = floorf((quatInput.w + 1.f) * QUAT_PART_CONVERSION_RATIO);
memcpy(buffer, &quatParts, sizeof(quatParts)); memcpy(buffer, &quatParts, sizeof(quatParts));
return sizeof(quatParts); return sizeof(quatParts);
@ -531,16 +531,16 @@ int unpackOrientationQuatFromBytes(const unsigned char* buffer, glm::quat& quatO
uint16_t quatParts[4]; uint16_t quatParts[4];
memcpy(&quatParts, buffer, sizeof(quatParts)); memcpy(&quatParts, buffer, sizeof(quatParts));
quatOutput.x = ((quatParts[0] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0; quatOutput.x = ((quatParts[0] / (float) std::numeric_limits<uint16_t>::max()) * 2.f) - 1.f;
quatOutput.y = ((quatParts[1] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0; quatOutput.y = ((quatParts[1] / (float) std::numeric_limits<uint16_t>::max()) * 2.f) - 1.f;
quatOutput.z = ((quatParts[2] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0; quatOutput.z = ((quatParts[2] / (float) std::numeric_limits<uint16_t>::max()) * 2.f) - 1.f;
quatOutput.w = ((quatParts[3] / (float) std::numeric_limits<uint16_t>::max()) * 2.0) - 1.0; quatOutput.w = ((quatParts[3] / (float) std::numeric_limits<uint16_t>::max()) * 2.f) - 1.f;
return sizeof(quatParts); return sizeof(quatParts);
} }
float SMALL_LIMIT = 10.0; float SMALL_LIMIT = 10.f;
float LARGE_LIMIT = 1000.0; float LARGE_LIMIT = 1000.f;
int packFloatRatioToTwoByte(unsigned char* buffer, float ratio) { int packFloatRatioToTwoByte(unsigned char* buffer, float ratio) {
// if the ratio is less than 10, then encode it as a positive number scaled from 0 to int16::max() // if the ratio is less than 10, then encode it as a positive number scaled from 0 to int16::max()
@ -642,24 +642,24 @@ glm::vec3 safeEulerAngles(const glm::quat& q) {
float sy = 2.0f * (q.y * q.w - q.x * q.z); float sy = 2.0f * (q.y * q.w - q.x * q.z);
if (sy < 1.0f - EPSILON) { if (sy < 1.0f - EPSILON) {
if (sy > -1.0f + EPSILON) { if (sy > -1.0f + EPSILON) {
return glm::degrees(glm::vec3( return glm::vec3(
atan2f(q.y * q.z + q.x * q.w, 0.5f - (q.x * q.x + q.y * q.y)), atan2f(q.y * q.z + q.x * q.w, 0.5f - (q.x * q.x + q.y * q.y)),
asinf(sy), asinf(sy),
atan2f(q.x * q.y + q.z * q.w, 0.5f - (q.y * q.y + q.z * q.z)))); atan2f(q.x * q.y + q.z * q.w, 0.5f - (q.y * q.y + q.z * q.z)));
} else { } else {
// not a unique solution; x + z = atan2(-m21, m11) // not a unique solution; x + z = atan2(-m21, m11)
return glm::degrees(glm::vec3( return glm::vec3(
0.0f, 0.0f,
PIf * -0.5f, - PI_OVER_TWO,
atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z)))); atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z)));
} }
} else { } else {
// not a unique solution; x - z = atan2(-m21, m11) // not a unique solution; x - z = atan2(-m21, m11)
return glm::degrees(glm::vec3( return glm::vec3(
0.0f, 0.0f,
PIf * 0.5f, PI_OVER_TWO,
-atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z)))); -atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z)));
} }
} }

View file

@ -47,9 +47,13 @@ static const float ZERO = 0.0f;
static const float ONE = 1.0f; static const float ONE = 1.0f;
static const float ONE_HALF = 0.5f; static const float ONE_HALF = 0.5f;
static const float ONE_THIRD = 0.333333f; static const float ONE_THIRD = 0.333333f;
static const float PIE = 3.141592f;
static const float PI_TIMES_TWO = 3.141592f * 2.0f; static const float PI = 3.14159265358979f;
static const float PI_OVER_180 = 3.141592f / 180.0f; static const float TWO_PI = 2.f * PI;
static const float PI_OVER_TWO = ONE_HALF * PI;
static const float RADIANS_PER_DEGREE = PI / 180.0f;
static const float DEGREES_PER_RADIAN = 180.0f / PI;
static const float EPSILON = 0.000001f; //smallish positive number - used as margin of error for some computations static const float EPSILON = 0.000001f; //smallish positive number - used as margin of error for some computations
static const float SQUARE_ROOT_OF_2 = (float)sqrt(2.f); static const float SQUARE_ROOT_OF_2 = (float)sqrt(2.f);
static const float SQUARE_ROOT_OF_3 = (float)sqrt(3.f); static const float SQUARE_ROOT_OF_3 = (float)sqrt(3.f);
@ -133,8 +137,8 @@ bool isBetween(int64_t value, int64_t max, int64_t min);
// These pack/unpack functions are designed to start specific known types in as efficient a manner // These pack/unpack functions are designed to start specific known types in as efficient a manner
// as possible. Taking advantage of the known characteristics of the semantic types. // as possible. Taking advantage of the known characteristics of the semantic types.
// Angles are known to be between 0 and 360deg, this allows us to encode in 16bits with great accuracy // Angles are known to be between 0 and 360 degrees, this allows us to encode in 16bits with great accuracy
int packFloatAngleToTwoByte(unsigned char* buffer, float angle); int packFloatAngleToTwoByte(unsigned char* buffer, float degrees);
int unpackFloatAngleFromTwoByte(const uint16_t* byteAnglePointer, float* destinationPointer); int unpackFloatAngleFromTwoByte(const uint16_t* byteAnglePointer, float* destinationPointer);
// Orientation Quats are known to have 4 normalized components be between -1.0 and 1.0 // Orientation Quats are known to have 4 normalized components be between -1.0 and 1.0
@ -164,10 +168,7 @@ int unpackFloatScalarFromSignedTwoByteFixed(const int16_t* byteFixedPointer, flo
int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix); int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix);
int unpackFloatVec3FromSignedTwoByteFixed(const unsigned char* sourceBuffer, glm::vec3& destination, int radix); int unpackFloatVec3FromSignedTwoByteFixed(const unsigned char* sourceBuffer, glm::vec3& destination, int radix);
#ifndef PIf /// \return vec3 with euler angles in radians
#define PIf 3.14159265f
#endif
glm::vec3 safeEulerAngles(const glm::quat& q); glm::vec3 safeEulerAngles(const glm::quat& q);
#endif /* defined(__hifi__SharedUtil__) */ #endif /* defined(__hifi__SharedUtil__) */

View file

@ -25,7 +25,7 @@ void CollisionInfoTests::rotateThenTranslate() {
collision._contactPoint = yAxis; collision._contactPoint = yAxis;
collision._addedVelocity = xAxis + yAxis + zAxis; collision._addedVelocity = xAxis + yAxis + zAxis;
glm::quat rotation = glm::angleAxis(rightAngle, zAxis); glm::quat rotation = glm::angleAxis(PI_OVER_TWO, zAxis);
float distance = 3.f; float distance = 3.f;
glm::vec3 translation = distance * yAxis; glm::vec3 translation = distance * yAxis;
@ -64,7 +64,7 @@ void CollisionInfoTests::translateThenRotate() {
collision._contactPoint = yAxis; collision._contactPoint = yAxis;
collision._addedVelocity = xAxis + yAxis + zAxis; collision._addedVelocity = xAxis + yAxis + zAxis;
glm::quat rotation = glm::angleAxis( -rightAngle, zAxis); glm::quat rotation = glm::angleAxis( -PI_OVER_TWO, zAxis);
float distance = 3.f; float distance = 3.f;
glm::vec3 translation = distance * yAxis; glm::vec3 translation = distance * yAxis;

View file

@ -18,8 +18,6 @@ const glm::vec3 xAxis(1.f, 0.f, 0.f);
const glm::vec3 yAxis(0.f, 1.f, 0.f); const glm::vec3 yAxis(0.f, 1.f, 0.f);
const glm::vec3 zAxis(0.f, 0.f, 1.f); const glm::vec3 zAxis(0.f, 0.f, 1.f);
const float rightAngle = 90.f; // degrees
std::ostream& operator<<(std::ostream& s, const glm::vec3& v); std::ostream& operator<<(std::ostream& s, const glm::vec3& v);
std::ostream& operator<<(std::ostream& s, const glm::quat& q); std::ostream& operator<<(std::ostream& s, const glm::quat& q);
std::ostream& operator<<(std::ostream& s, const glm::mat4& m); std::ostream& operator<<(std::ostream& s, const glm::mat4& m);

View file

@ -485,7 +485,7 @@ void ShapeColliderTests::capsuleMissesCapsule() {
} }
// rotate B and move it to the side // rotate B and move it to the side
glm::quat rotation = glm::angleAxis(rightAngle, zAxis); glm::quat rotation = glm::angleAxis(PI_OVER_TWO, zAxis);
capsuleB.setRotation(rotation); capsuleB.setRotation(rotation);
capsuleB.setPosition((1.01f * (totalRadius + capsuleB.getHalfHeight())) * xAxis); capsuleB.setPosition((1.01f * (totalRadius + capsuleB.getHalfHeight())) * xAxis);
if (ShapeCollider::shapeShape(&capsuleA, &capsuleB, collisions)) if (ShapeCollider::shapeShape(&capsuleA, &capsuleB, collisions))
@ -566,7 +566,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
} }
{ // rotate B and move it to the side { // rotate B and move it to the side
glm::quat rotation = glm::angleAxis(rightAngle, zAxis); glm::quat rotation = glm::angleAxis(PI_OVER_TWO, zAxis);
capsuleB.setRotation(rotation); capsuleB.setRotation(rotation);
capsuleB.setPosition((0.99f * (totalRadius + capsuleB.getHalfHeight())) * xAxis); capsuleB.setPosition((0.99f * (totalRadius + capsuleB.getHalfHeight())) * xAxis);
@ -590,7 +590,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
{ // again, but this time check collision details { // again, but this time check collision details
float overlap = 0.1f; float overlap = 0.1f;
glm::quat rotation = glm::angleAxis(rightAngle, zAxis); glm::quat rotation = glm::angleAxis(PI_OVER_TWO, zAxis);
capsuleB.setRotation(rotation); capsuleB.setRotation(rotation);
glm::vec3 positionB = ((totalRadius + capsuleB.getHalfHeight()) - overlap) * xAxis; glm::vec3 positionB = ((totalRadius + capsuleB.getHalfHeight()) - overlap) * xAxis;
capsuleB.setPosition(positionB); capsuleB.setPosition(positionB);
@ -657,7 +657,7 @@ void ShapeColliderTests::capsuleTouchesCapsule() {
{ // collide cylinder wall against cylinder wall { // collide cylinder wall against cylinder wall
float overlap = 0.137f; float overlap = 0.137f;
float shift = 0.317f * halfHeightA; float shift = 0.317f * halfHeightA;
glm::quat rotation = glm::angleAxis(rightAngle, zAxis); glm::quat rotation = glm::angleAxis(PI_OVER_TWO, zAxis);
capsuleB.setRotation(rotation); capsuleB.setRotation(rotation);
glm::vec3 positionB = (totalRadius - overlap) * zAxis + shift * yAxis; glm::vec3 positionB = (totalRadius - overlap) * zAxis + shift * yAxis;
capsuleB.setPosition(positionB); capsuleB.setPosition(positionB);