diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt
index 3fb0f574a5..2f3739485a 100644
--- a/assignment-client/CMakeLists.txt
+++ b/assignment-client/CMakeLists.txt
@@ -9,9 +9,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake
 include("${MACRO_DIR}/SetupHifiProject.cmake")
 setup_hifi_project(${TARGET_NAME} TRUE)
 
-include(${MACRO_DIR}/IncludeGLM.cmake)
-include_glm(${TARGET_NAME} "${ROOT_DIR}")
-
 # link in the shared libraries
 include(${MACRO_DIR}/LinkHifiLibrary.cmake)
 link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}")
@@ -29,19 +26,15 @@ link_hifi_library(script-engine ${TARGET_NAME} "${ROOT_DIR}")
 link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}")
 
 if (UNIX)
-  list(APPEND DEPENDENCY_LIBRARIES ${CMAKE_DL_LIBS})
+  target_link_libraries(${TARGET_NAME} ${DEPENDENCY_LIBRARIES} ${CMAKE_DL_LIBS})
 endif (UNIX)
 
 IF (WIN32)
-  list(APPEND DEPENDENCY_LIBRARIES Winmm Ws2_32)
+  target_link_libraries(${TARGET_NAME} ${DEPENDENCY_LIBRARIES} Winmm Ws2_32)
 ENDIF(WIN32)
 
 find_package(Qt5 COMPONENTS Gui Network Script Widgets)
-
-# set a property indicating the libraries we are dependent on and link them to ourselves
-list(APPEND DEPENDENCY_LIBRARIES Qt5::Gui Qt5::Network Qt5::Script Qt5::Widgets)
-set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_LIBRARIES "${DEPENDENCY_LIBRARIES}")
-target_link_libraries(${TARGET_NAME} ${DEPENDENCY_LIBRARIES})
+target_link_libraries(${TARGET_NAME} Qt5::Gui Qt5::Network Qt5::Script Qt5::Widgets)
 
 # add a definition for ssize_t so that windows doesn't bail
 if (WIN32)
diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt
index 26f07cf776..656760957d 100644
--- a/domain-server/CMakeLists.txt
+++ b/domain-server/CMakeLists.txt
@@ -32,4 +32,7 @@ ENDIF(WIN32)
 # add a definition for ssize_t so that windows doesn't bail
 if (WIN32)
   add_definitions(-Dssize_t=long)
-endif ()
\ No newline at end of file
+endif ()
+
+find_package(Qt5 COMPONENTS Network)
+target_link_libraries(${TARGET_NAME} Qt5::Network)
diff --git a/libraries/shared/src/AngularConstraint.cpp b/libraries/shared/src/AngularConstraint.cpp
index 4689568ac8..b39823ee3b 100644
--- a/libraries/shared/src/AngularConstraint.cpp
+++ b/libraries/shared/src/AngularConstraint.cpp
@@ -11,8 +11,9 @@
 
 #include <glm/gtx/norm.hpp>
 
+#include "GLMHelpers.h"
+
 #include "AngularConstraint.h"
-#include "SharedUtil.h"
 
 // helper function
 /// \param angle radian angle to be clamped within angleMin and angleMax
diff --git a/libraries/shared/src/AngularConstraint.h b/libraries/shared/src/AngularConstraint.h
index 929a58959b..74d3fdb82b 100644
--- a/libraries/shared/src/AngularConstraint.h
+++ b/libraries/shared/src/AngularConstraint.h
@@ -14,7 +14,6 @@
 
 #include <glm/glm.hpp>
 
-
 class AngularConstraint {
 public:
     /// \param minAngles minumum euler angles for the constraint
diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp
new file mode 100644
index 0000000000..566983679b
--- /dev/null
+++ b/libraries/shared/src/GLMHelpers.cpp
@@ -0,0 +1,299 @@
+//
+//  GLMHelpers.cpp
+//  libraries/shared/src
+//
+//  Created by Stephen Birarda on 2014-08-07.
+//  Copyright 2014 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#include "GLMHelpers.h"
+
+//  Safe version of glm::mix; based on the code in Nick Bobick's article,
+//  http://www.gamasutra.com/features/19980703/quaternions_01.htm (via Clyde,
+//  https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java)
+glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float proportion) {
+    float cosa = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w;
+    float ox = q2.x, oy = q2.y, oz = q2.z, ow = q2.w, s0, s1;
+    
+    // adjust signs if necessary
+    if (cosa < 0.0f) {
+        cosa = -cosa;
+        ox = -ox;
+        oy = -oy;
+        oz = -oz;
+        ow = -ow;
+    }
+    
+    // calculate coefficients; if the angle is too close to zero, we must fall back
+    // to linear interpolation
+    if ((1.0f - cosa) > EPSILON) {
+        float angle = acosf(cosa), sina = sinf(angle);
+        s0 = sinf((1.0f - proportion) * angle) / sina;
+        s1 = sinf(proportion * angle) / sina;
+        
+    } else {
+        s0 = 1.0f - proportion;
+        s1 = proportion;
+    }
+    
+    return glm::normalize(glm::quat(s0 * q1.w + s1 * ow, s0 * q1.x + s1 * ox, s0 * q1.y + s1 * oy, s0 * q1.z + s1 * oz));
+}
+
+// Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc
+int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix) {
+    int16_t outVal = (int16_t)(scalar * (float)(1 << radix));
+    memcpy(buffer, &outVal, sizeof(uint16_t));
+    return sizeof(uint16_t);
+}
+
+int unpackFloatScalarFromSignedTwoByteFixed(const int16_t* byteFixedPointer, float* destinationPointer, int radix) {
+    *destinationPointer = *byteFixedPointer / (float)(1 << radix);
+    return sizeof(int16_t);
+}
+
+int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix) {
+    const unsigned char* startPosition = destBuffer;
+    destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.x, radix);
+    destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.y, radix);
+    destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.z, radix);
+    return destBuffer - startPosition;
+}
+
+int unpackFloatVec3FromSignedTwoByteFixed(const unsigned char* sourceBuffer, glm::vec3& destination, int radix) {
+    const unsigned char* startPosition = sourceBuffer;
+    sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.x), radix);
+    sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.y), radix);
+    sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.z), radix);
+    return sourceBuffer - startPosition;
+}
+
+
+int packFloatAngleToTwoByte(unsigned char* buffer, float degrees) {
+    const float ANGLE_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 360.f);
+    
+    uint16_t angleHolder = floorf((degrees + 180.f) * ANGLE_CONVERSION_RATIO);
+    memcpy(buffer, &angleHolder, sizeof(uint16_t));
+    
+    return sizeof(uint16_t);
+}
+
+int unpackFloatAngleFromTwoByte(const uint16_t* byteAnglePointer, float* destinationPointer) {
+    *destinationPointer = (*byteAnglePointer / (float) std::numeric_limits<uint16_t>::max()) * 360.f - 180.f;
+    return sizeof(uint16_t);
+}
+
+int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput) {
+    const float QUAT_PART_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 2.f);
+    uint16_t quatParts[4];
+    quatParts[0] = floorf((quatInput.x + 1.f) * QUAT_PART_CONVERSION_RATIO);
+    quatParts[1] = floorf((quatInput.y + 1.f) * QUAT_PART_CONVERSION_RATIO);
+    quatParts[2] = floorf((quatInput.z + 1.f) * QUAT_PART_CONVERSION_RATIO);
+    quatParts[3] = floorf((quatInput.w + 1.f) * QUAT_PART_CONVERSION_RATIO);
+    
+    memcpy(buffer, &quatParts, sizeof(quatParts));
+    return sizeof(quatParts);
+}
+
+int unpackOrientationQuatFromBytes(const unsigned char* buffer, glm::quat& quatOutput) {
+    uint16_t quatParts[4];
+    memcpy(&quatParts, buffer, sizeof(quatParts));
+    
+    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.f) - 1.f;
+    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.f) - 1.f;
+    
+    return sizeof(quatParts);
+}
+
+//  Safe version of glm::eulerAngles; uses the factorization method described in David Eberly's
+//  http://www.geometrictools.com/Documentation/EulerAngles.pdf (via Clyde,
+// https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java)
+glm::vec3 safeEulerAngles(const glm::quat& q) {
+    float sy = 2.0f * (q.y * q.w - q.x * q.z);
+    glm::vec3 eulers;
+    if (sy < 1.0f - EPSILON) {
+        if (sy > -1.0f + EPSILON) {
+            eulers = glm::vec3(
+                               atan2f(q.y * q.z + q.x * q.w, 0.5f - (q.x * q.x + q.y * q.y)),
+                               asinf(sy),
+                               atan2f(q.x * q.y + q.z * q.w, 0.5f - (q.y * q.y + q.z * q.z)));
+            
+        } else {
+            // not a unique solution; x + z = atan2(-m21, m11)
+            eulers = glm::vec3(
+                               0.0f,
+                               - PI_OVER_TWO,
+                               atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z)));
+        }
+    } else {
+        // not a unique solution; x - z = atan2(-m21, m11)
+        eulers = glm::vec3(
+                           0.0f,
+                           PI_OVER_TWO,
+                           -atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z)));
+    }
+    
+    // adjust so that z, rather than y, is in [-pi/2, pi/2]
+    if (eulers.z < -PI_OVER_TWO) {
+        if (eulers.x < 0.0f) {
+            eulers.x += PI;
+        } else {
+            eulers.x -= PI;
+        }
+        eulers.y = -eulers.y;
+        if (eulers.y < 0.0f) {
+            eulers.y += PI;
+        } else {
+            eulers.y -= PI;
+        }
+        eulers.z += PI;
+        
+    } else if (eulers.z > PI_OVER_TWO) {
+        if (eulers.x < 0.0f) {
+            eulers.x += PI;
+        } else {
+            eulers.x -= PI;
+        }
+        eulers.y = -eulers.y;
+        if (eulers.y < 0.0f) {
+            eulers.y += PI;
+        } else {
+            eulers.y -= PI;
+        }
+        eulers.z -= PI;
+    }
+    return eulers;
+}
+
+//  Helper function returns the positive angle (in radians) between two 3D vectors
+float angleBetween(const glm::vec3& v1, const glm::vec3& v2) {
+    return acosf((glm::dot(v1, v2)) / (glm::length(v1) * glm::length(v2)));
+}
+
+//  Helper function return the rotation from the first vector onto the second
+glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2) {
+    float angle = angleBetween(v1, v2);
+    if (glm::isnan(angle) || angle < EPSILON) {
+        return glm::quat();
+    }
+    glm::vec3 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));
+        float axisLength = glm::length(axis);
+        if (axisLength < EPSILON) { // parallel to x; y will work
+            axis = glm::normalize(glm::cross(v1, glm::vec3(0.0f, 1.0f, 0.0f)));
+        } else {
+            axis /= axisLength;
+        }
+    } else {
+        axis = glm::normalize(glm::cross(v1, v2));
+        // It is possible for axis to be nan even when angle is not less than EPSILON.
+        // For example when angle is small but not tiny but v1 and v2 and have very short lengths.
+        if (glm::isnan(glm::dot(axis, axis))) {
+            // set angle and axis to values that will generate an identity rotation
+            angle = 0.0f;
+            axis = glm::vec3(1.0f, 0.0f, 0.0f);
+        }
+    }
+    return glm::angleAxis(angle, axis);
+}
+
+glm::vec3 extractTranslation(const glm::mat4& matrix) {
+    return glm::vec3(matrix[3][0], matrix[3][1], matrix[3][2]);
+}
+
+void setTranslation(glm::mat4& matrix, const glm::vec3& translation) {
+    matrix[3][0] = translation.x;
+    matrix[3][1] = translation.y;
+    matrix[3][2] = translation.z;
+}
+
+glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal) {
+    // uses the iterative polar decomposition algorithm described by Ken Shoemake at
+    // http://www.cs.wisc.edu/graphics/Courses/838-s2002/Papers/polar-decomp.pdf
+    // code adapted from Clyde, https://github.com/threerings/clyde/blob/master/core/src/main/java/com/threerings/math/Matrix4f.java
+    // start with the contents of the upper 3x3 portion of the matrix
+    glm::mat3 upper = glm::mat3(matrix);
+    if (!assumeOrthogonal) {
+        for (int i = 0; i < 10; i++) {
+            // store the results of the previous iteration
+            glm::mat3 previous = upper;
+            
+            // compute average of the matrix with its inverse transpose
+            float sd00 = previous[1][1] * previous[2][2] - previous[2][1] * previous[1][2];
+            float sd10 = previous[0][1] * previous[2][2] - previous[2][1] * previous[0][2];
+            float sd20 = previous[0][1] * previous[1][2] - previous[1][1] * previous[0][2];
+            float det = previous[0][0] * sd00 + previous[2][0] * sd20 - previous[1][0] * sd10;
+            if (fabs(det) == 0.0f) {
+                // determinant is zero; matrix is not invertible
+                break;
+            }
+            float hrdet = 0.5f / det;
+            upper[0][0] = +sd00 * hrdet + previous[0][0] * 0.5f;
+            upper[1][0] = -sd10 * hrdet + previous[1][0] * 0.5f;
+            upper[2][0] = +sd20 * hrdet + previous[2][0] * 0.5f;
+            
+            upper[0][1] = -(previous[1][0] * previous[2][2] - previous[2][0] * previous[1][2]) * hrdet + previous[0][1] * 0.5f;
+            upper[1][1] = +(previous[0][0] * previous[2][2] - previous[2][0] * previous[0][2]) * hrdet + previous[1][1] * 0.5f;
+            upper[2][1] = -(previous[0][0] * previous[1][2] - previous[1][0] * previous[0][2]) * hrdet + previous[2][1] * 0.5f;
+            
+            upper[0][2] = +(previous[1][0] * previous[2][1] - previous[2][0] * previous[1][1]) * hrdet + previous[0][2] * 0.5f;
+            upper[1][2] = -(previous[0][0] * previous[2][1] - previous[2][0] * previous[0][1]) * hrdet + previous[1][2] * 0.5f;
+            upper[2][2] = +(previous[0][0] * previous[1][1] - previous[1][0] * previous[0][1]) * hrdet + previous[2][2] * 0.5f;
+            
+            // compute the difference; if it's small enough, we're done
+            glm::mat3 diff = upper - previous;
+            if (diff[0][0] * diff[0][0] + diff[1][0] * diff[1][0] + diff[2][0] * diff[2][0] + diff[0][1] * diff[0][1] +
+                diff[1][1] * diff[1][1] + diff[2][1] * diff[2][1] + diff[0][2] * diff[0][2] + diff[1][2] * diff[1][2] +
+                diff[2][2] * diff[2][2] < EPSILON) {
+                break;
+            }
+        }
+    }
+    
+    // now that we have a nice orthogonal matrix, we can extract the rotation quaternion
+    // using the method described in http://en.wikipedia.org/wiki/Rotation_matrix#Conversions
+    float x2 = fabs(1.0f + upper[0][0] - upper[1][1] - upper[2][2]);
+    float y2 = fabs(1.0f - upper[0][0] + upper[1][1] - upper[2][2]);
+    float z2 = fabs(1.0f - upper[0][0] - upper[1][1] + upper[2][2]);
+    float w2 = fabs(1.0f + upper[0][0] + upper[1][1] + upper[2][2]);
+    return glm::normalize(glm::quat(0.5f * sqrtf(w2),
+                                    0.5f * sqrtf(x2) * (upper[1][2] >= upper[2][1] ? 1.0f : -1.0f),
+                                    0.5f * sqrtf(y2) * (upper[2][0] >= upper[0][2] ? 1.0f : -1.0f),
+                                    0.5f * sqrtf(z2) * (upper[0][1] >= upper[1][0] ? 1.0f : -1.0f)));
+}
+
+glm::vec3 extractScale(const glm::mat4& matrix) {
+    return glm::vec3(glm::length(matrix[0]), glm::length(matrix[1]), glm::length(matrix[2]));
+}
+
+float extractUniformScale(const glm::mat4& matrix) {
+    return extractUniformScale(extractScale(matrix));
+}
+
+float extractUniformScale(const glm::vec3& scale) {
+    return (scale.x + scale.y + scale.z) / 3.0f;
+}
+
+QByteArray createByteArray(const glm::vec3& vector) {
+    return QByteArray::number(vector.x) + ',' + QByteArray::number(vector.y) + ',' + QByteArray::number(vector.z);
+}
+
+bool isSimilarOrientation(const glm::quat& orientionA, const glm::quat& orientionB, float similarEnough) {
+    // Compute the angular distance between the two orientations
+    float angleOrientation = orientionA == orientionB ? 0.0f : glm::degrees(glm::angle(orientionA * glm::inverse(orientionB)));
+    if (isNaN(angleOrientation)) {
+        angleOrientation = 0.0f;
+    }
+    return (angleOrientation <= similarEnough);
+}
+
+bool isSimilarPosition(const glm::vec3& positionA, const glm::vec3& positionB, float similarEnough) {
+    // Compute the distance between the two points
+    float positionDistance = glm::distance(positionA, positionB);
+    return (positionDistance <= similarEnough);
+}
\ No newline at end of file
diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h
new file mode 100644
index 0000000000..43a1d09722
--- /dev/null
+++ b/libraries/shared/src/GLMHelpers.h
@@ -0,0 +1,89 @@
+//
+//  GLMHelpers.h
+//  libraries/shared/src
+//
+//  Created by Stephen Birarda on 2014-08-07.
+//  Copyright 2014 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#ifndef hifi_GLMHelpers_h
+#define hifi_GLMHelpers_h
+
+#include <stdint.h>
+
+#include <glm/glm.hpp>
+#include <glm/gtc/quaternion.hpp>
+
+#include <QtCore/QByteArray>
+
+#include "SharedUtil.h"
+
+glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float alpha);
+
+// 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.
+
+// 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 degrees);
+int unpackFloatAngleFromTwoByte(const uint16_t* byteAnglePointer, float* destinationPointer);
+
+// Orientation Quats are known to have 4 normalized components be between -1.0 and 1.0
+// this allows us to encode each component in 16bits with great accuracy
+int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput);
+int unpackOrientationQuatFromBytes(const unsigned char* buffer, glm::quat& quatOutput);
+
+// Ratios need the be highly accurate when less than 10, but not very accurate above 10, and they
+// are never greater than 1000 to 1, this allows us to encode each component in 16bits
+int packFloatRatioToTwoByte(unsigned char* buffer, float ratio);
+int unpackFloatRatioFromTwoByte(const unsigned char* buffer, float& ratio);
+
+// Near/Far Clip values need the be highly accurate when less than 10, but only integer accuracy above 10 and
+// they are never greater than 16,000, this allows us to encode each component in 16bits
+int packClipValueToTwoByte(unsigned char* buffer, float clipValue);
+int unpackClipValueFromTwoByte(const unsigned char* buffer, float& clipValue);
+
+// Positive floats that don't need to be very precise
+int packFloatToByte(unsigned char* buffer, float value, float scaleBy);
+int unpackFloatFromByte(const unsigned char* buffer, float& value, float scaleBy);
+
+// Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc
+int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix);
+int unpackFloatScalarFromSignedTwoByteFixed(const int16_t* byteFixedPointer, float* destinationPointer, int radix);
+
+// A convenience for sending vec3's as fixed-point floats
+int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix);
+int unpackFloatVec3FromSignedTwoByteFixed(const unsigned char* sourceBuffer, glm::vec3& destination, int radix);
+
+/// \return vec3 with euler angles in radians
+glm::vec3 safeEulerAngles(const glm::quat& q);
+
+float angleBetween(const glm::vec3& v1, const glm::vec3& v2);
+
+glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2);
+
+glm::vec3 extractTranslation(const glm::mat4& matrix);
+
+void setTranslation(glm::mat4& matrix, const glm::vec3& translation);
+
+glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal = false);
+
+glm::vec3 extractScale(const glm::mat4& matrix);
+
+float extractUniformScale(const glm::mat4& matrix);
+
+float extractUniformScale(const glm::vec3& scale);
+
+QByteArray createByteArray(const glm::vec3& vector);
+
+/// \return bool are two orientations similar to each other
+const float ORIENTATION_SIMILAR_ENOUGH = 5.0f; // 10 degrees in any direction
+bool isSimilarOrientation(const glm::quat& orientionA, const glm::quat& orientionB,
+                          float similarEnough = ORIENTATION_SIMILAR_ENOUGH);
+const float POSITION_SIMILAR_ENOUGH = 0.1f; // 0.1 meter
+bool isSimilarPosition(const glm::vec3& positionA, const glm::vec3& positionB, float similarEnough = POSITION_SIMILAR_ENOUGH);
+
+
+#endif // hifi_GLMHelpers_h
\ No newline at end of file
diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp
index 2b8b9929e5..470dfffd13 100644
--- a/libraries/shared/src/SharedUtil.cpp
+++ b/libraries/shared/src/SharedUtil.cpp
@@ -79,40 +79,6 @@ bool shouldDo(float desiredInterval, float deltaTime) {
     return randFloat() < deltaTime / desiredInterval;
 }
 
-//  Safe version of glm::mix; based on the code in Nick Bobick's article,
-//  http://www.gamasutra.com/features/19980703/quaternions_01.htm (via Clyde,
-//  https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java)
-glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float proportion) {
-    float cosa = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w;
-    float ox = q2.x, oy = q2.y, oz = q2.z, ow = q2.w, s0, s1;
-    
-    // adjust signs if necessary
-    if (cosa < 0.0f) {
-        cosa = -cosa;
-        ox = -ox;
-        oy = -oy;
-        oz = -oz;
-        ow = -ow;
-    }
-    
-    // calculate coefficients; if the angle is too close to zero, we must fall back
-    // to linear interpolation
-    if ((1.0f - cosa) > EPSILON) {
-        float angle = acosf(cosa), sina = sinf(angle);
-        s0 = sinf((1.0f - proportion) * angle) / sina;
-        s1 = sinf(proportion * angle) / sina;
-        
-    } else {
-        s0 = 1.0f - proportion;
-        s1 = proportion;
-    }
-    
-    return glm::normalize(glm::quat(s0 * q1.w + s1 * ow, s0 * q1.x + s1 * ox, s0 * q1.y + s1 * oy, s0 * q1.z + s1 * oz));
-}
-
-
-
-
 void outputBufferBits(const unsigned char* buffer, int length, QDebug* continuedDebug) {
     for (int i = 0; i < length; i++) {
         outputBits(buffer[i], continuedDebug);
@@ -489,73 +455,6 @@ int removeFromSortedArrays(void* value, void** valueArray, float* keyArray, int*
     return -1; // error case
 }
 
-// Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc
-int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix) {
-    int16_t outVal = (int16_t)(scalar * (float)(1 << radix));
-    memcpy(buffer, &outVal, sizeof(uint16_t));
-    return sizeof(uint16_t);
-}
-
-int unpackFloatScalarFromSignedTwoByteFixed(const int16_t* byteFixedPointer, float* destinationPointer, int radix) {
-    *destinationPointer = *byteFixedPointer / (float)(1 << radix);
-    return sizeof(int16_t);
-}
-
-int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix) {
-    const unsigned char* startPosition = destBuffer;
-    destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.x, radix);
-    destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.y, radix);
-    destBuffer += packFloatScalarToSignedTwoByteFixed(destBuffer, srcVector.z, radix);
-    return destBuffer - startPosition;
-}
-
-int unpackFloatVec3FromSignedTwoByteFixed(const unsigned char* sourceBuffer, glm::vec3& destination, int radix) {
-    const unsigned char* startPosition = sourceBuffer;
-    sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.x), radix);
-    sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.y), radix);
-    sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((int16_t*) sourceBuffer, &(destination.z), radix);
-    return sourceBuffer - startPosition;
-}
-
-
-int packFloatAngleToTwoByte(unsigned char* buffer, float degrees) {
-    const float ANGLE_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 360.f);
-
-    uint16_t angleHolder = floorf((degrees + 180.f) * ANGLE_CONVERSION_RATIO);
-    memcpy(buffer, &angleHolder, sizeof(uint16_t));
-
-    return sizeof(uint16_t);
-}
-
-int unpackFloatAngleFromTwoByte(const uint16_t* byteAnglePointer, float* destinationPointer) {
-    *destinationPointer = (*byteAnglePointer / (float) std::numeric_limits<uint16_t>::max()) * 360.f - 180.f;
-    return sizeof(uint16_t);
-}
-
-int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput) {
-    const float QUAT_PART_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 2.f);
-    uint16_t quatParts[4];
-    quatParts[0] = floorf((quatInput.x + 1.f) * QUAT_PART_CONVERSION_RATIO);
-    quatParts[1] = floorf((quatInput.y + 1.f) * QUAT_PART_CONVERSION_RATIO);
-    quatParts[2] = floorf((quatInput.z + 1.f) * QUAT_PART_CONVERSION_RATIO);
-    quatParts[3] = floorf((quatInput.w + 1.f) * QUAT_PART_CONVERSION_RATIO);
-
-    memcpy(buffer, &quatParts, sizeof(quatParts));
-    return sizeof(quatParts);
-}
-
-int unpackOrientationQuatFromBytes(const unsigned char* buffer, glm::quat& quatOutput) {
-    uint16_t quatParts[4];
-    memcpy(&quatParts, buffer, sizeof(quatParts));
-
-    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.f) - 1.f;
-    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.f) - 1.f;
-
-    return sizeof(quatParts);
-}
-
 float SMALL_LIMIT = 10.f;
 float LARGE_LIMIT = 1000.f;
 
@@ -651,199 +550,10 @@ void debug::checkDeadBeef(void* memoryVoid, int size) {
     assert(memcmp((unsigned char*)memoryVoid, DEADBEEF, std::min(size, DEADBEEF_SIZE)) != 0);
 }
 
-//  Safe version of glm::eulerAngles; uses the factorization method described in David Eberly's
-//  http://www.geometrictools.com/Documentation/EulerAngles.pdf (via Clyde,
-// https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java)
-glm::vec3 safeEulerAngles(const glm::quat& q) {
-    float sy = 2.0f * (q.y * q.w - q.x * q.z);
-    glm::vec3 eulers;
-    if (sy < 1.0f - EPSILON) {
-        if (sy > -1.0f + EPSILON) {
-            eulers = glm::vec3(
-                atan2f(q.y * q.z + q.x * q.w, 0.5f - (q.x * q.x + q.y * q.y)),
-                asinf(sy),
-                atan2f(q.x * q.y + q.z * q.w, 0.5f - (q.y * q.y + q.z * q.z)));
-
-        } else {
-            // not a unique solution; x + z = atan2(-m21, m11)
-            eulers = glm::vec3(
-                0.0f,
-                - PI_OVER_TWO,
-                atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z)));
-        }
-    } else {
-        // not a unique solution; x - z = atan2(-m21, m11)
-        eulers = glm::vec3(
-            0.0f,
-            PI_OVER_TWO,
-            -atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z)));
-    }
-    
-    // adjust so that z, rather than y, is in [-pi/2, pi/2]
-    if (eulers.z < -PI_OVER_TWO) {
-        if (eulers.x < 0.0f) {
-            eulers.x += PI;
-        } else {
-            eulers.x -= PI;
-        }
-        eulers.y = -eulers.y;
-        if (eulers.y < 0.0f) {
-            eulers.y += PI;
-        } else {
-            eulers.y -= PI;
-        }
-        eulers.z += PI;
-        
-    } else if (eulers.z > PI_OVER_TWO) {
-        if (eulers.x < 0.0f) {
-            eulers.x += PI;
-        } else {
-            eulers.x -= PI;
-        }
-        eulers.y = -eulers.y;
-        if (eulers.y < 0.0f) {
-            eulers.y += PI;
-        } else {
-            eulers.y -= PI;
-        }
-        eulers.z -= PI;
-    }
-    return eulers;
-}
-
-//  Helper function returns the positive angle (in radians) between two 3D vectors
-float angleBetween(const glm::vec3& v1, const glm::vec3& v2) {
-    return acosf((glm::dot(v1, v2)) / (glm::length(v1) * glm::length(v2)));
-}
-
-//  Helper function return the rotation from the first vector onto the second
-glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2) {
-    float angle = angleBetween(v1, v2);
-    if (glm::isnan(angle) || angle < EPSILON) {
-        return glm::quat();
-    }
-    glm::vec3 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));
-        float axisLength = glm::length(axis);
-        if (axisLength < EPSILON) { // parallel to x; y will work
-            axis = glm::normalize(glm::cross(v1, glm::vec3(0.0f, 1.0f, 0.0f)));
-        } else {
-            axis /= axisLength;
-        }
-    } else {
-        axis = glm::normalize(glm::cross(v1, v2));
-        // It is possible for axis to be nan even when angle is not less than EPSILON.
-        // For example when angle is small but not tiny but v1 and v2 and have very short lengths.
-        if (glm::isnan(glm::dot(axis, axis))) {
-            // set angle and axis to values that will generate an identity rotation
-            angle = 0.0f;
-            axis = glm::vec3(1.0f, 0.0f, 0.0f);
-        }
-    }
-    return glm::angleAxis(angle, axis);
-}
-
-glm::vec3 extractTranslation(const glm::mat4& matrix) {
-    return glm::vec3(matrix[3][0], matrix[3][1], matrix[3][2]);
-}
-
-void setTranslation(glm::mat4& matrix, const glm::vec3& translation) {
-    matrix[3][0] = translation.x;
-    matrix[3][1] = translation.y;
-    matrix[3][2] = translation.z;
-}
-
-glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal) {
-    // uses the iterative polar decomposition algorithm described by Ken Shoemake at
-    // http://www.cs.wisc.edu/graphics/Courses/838-s2002/Papers/polar-decomp.pdf
-    // code adapted from Clyde, https://github.com/threerings/clyde/blob/master/core/src/main/java/com/threerings/math/Matrix4f.java
-    // start with the contents of the upper 3x3 portion of the matrix
-    glm::mat3 upper = glm::mat3(matrix);
-    if (!assumeOrthogonal) {
-        for (int i = 0; i < 10; i++) {
-            // store the results of the previous iteration
-            glm::mat3 previous = upper;
-
-            // compute average of the matrix with its inverse transpose
-            float sd00 = previous[1][1] * previous[2][2] - previous[2][1] * previous[1][2];
-            float sd10 = previous[0][1] * previous[2][2] - previous[2][1] * previous[0][2];
-            float sd20 = previous[0][1] * previous[1][2] - previous[1][1] * previous[0][2];
-            float det = previous[0][0] * sd00 + previous[2][0] * sd20 - previous[1][0] * sd10;
-            if (fabs(det) == 0.0f) {
-                // determinant is zero; matrix is not invertible
-                break;
-            }
-            float hrdet = 0.5f / det;
-            upper[0][0] = +sd00 * hrdet + previous[0][0] * 0.5f;
-            upper[1][0] = -sd10 * hrdet + previous[1][0] * 0.5f;
-            upper[2][0] = +sd20 * hrdet + previous[2][0] * 0.5f;
-
-            upper[0][1] = -(previous[1][0] * previous[2][2] - previous[2][0] * previous[1][2]) * hrdet + previous[0][1] * 0.5f;
-            upper[1][1] = +(previous[0][0] * previous[2][2] - previous[2][0] * previous[0][2]) * hrdet + previous[1][1] * 0.5f;
-            upper[2][1] = -(previous[0][0] * previous[1][2] - previous[1][0] * previous[0][2]) * hrdet + previous[2][1] * 0.5f;
-
-            upper[0][2] = +(previous[1][0] * previous[2][1] - previous[2][0] * previous[1][1]) * hrdet + previous[0][2] * 0.5f;
-            upper[1][2] = -(previous[0][0] * previous[2][1] - previous[2][0] * previous[0][1]) * hrdet + previous[1][2] * 0.5f;
-            upper[2][2] = +(previous[0][0] * previous[1][1] - previous[1][0] * previous[0][1]) * hrdet + previous[2][2] * 0.5f;
-
-            // compute the difference; if it's small enough, we're done
-            glm::mat3 diff = upper - previous;
-            if (diff[0][0] * diff[0][0] + diff[1][0] * diff[1][0] + diff[2][0] * diff[2][0] + diff[0][1] * diff[0][1] +
-                    diff[1][1] * diff[1][1] + diff[2][1] * diff[2][1] + diff[0][2] * diff[0][2] + diff[1][2] * diff[1][2] +
-                    diff[2][2] * diff[2][2] < EPSILON) {
-                break;
-            }
-        }
-    }
-
-    // now that we have a nice orthogonal matrix, we can extract the rotation quaternion
-    // using the method described in http://en.wikipedia.org/wiki/Rotation_matrix#Conversions
-    float x2 = fabs(1.0f + upper[0][0] - upper[1][1] - upper[2][2]);
-    float y2 = fabs(1.0f - upper[0][0] + upper[1][1] - upper[2][2]);
-    float z2 = fabs(1.0f - upper[0][0] - upper[1][1] + upper[2][2]);
-    float w2 = fabs(1.0f + upper[0][0] + upper[1][1] + upper[2][2]);
-    return glm::normalize(glm::quat(0.5f * sqrtf(w2),
-        0.5f * sqrtf(x2) * (upper[1][2] >= upper[2][1] ? 1.0f : -1.0f),
-        0.5f * sqrtf(y2) * (upper[2][0] >= upper[0][2] ? 1.0f : -1.0f),
-        0.5f * sqrtf(z2) * (upper[0][1] >= upper[1][0] ? 1.0f : -1.0f)));
-}
-
-glm::vec3 extractScale(const glm::mat4& matrix) {
-    return glm::vec3(glm::length(matrix[0]), glm::length(matrix[1]), glm::length(matrix[2]));
-}
-
-float extractUniformScale(const glm::mat4& matrix) {
-    return extractUniformScale(extractScale(matrix));
-}
-
-float extractUniformScale(const glm::vec3& scale) {
-    return (scale.x + scale.y + scale.z) / 3.0f;
-}
-
 bool isNaN(float value) { 
     return value != value; 
 }
 
-bool isSimilarOrientation(const glm::quat& orientionA, const glm::quat& orientionB, float similarEnough) {
-    // Compute the angular distance between the two orientations
-    float angleOrientation = orientionA == orientionB ? 0.0f : glm::degrees(glm::angle(orientionA * glm::inverse(orientionB)));
-    if (isNaN(angleOrientation)) {
-        angleOrientation = 0.0f;
-    }
-    return (angleOrientation <= similarEnough);
-}
-
-bool isSimilarPosition(const glm::vec3& positionA, const glm::vec3& positionB, float similarEnough) {
-    // Compute the distance between the two points
-    float positionDistance = glm::distance(positionA, positionB);
-    return (positionDistance <= similarEnough);
-}
-
-QByteArray createByteArray(const glm::vec3& vector) {
-    return QByteArray::number(vector.x) + ',' + QByteArray::number(vector.y) + ',' + QByteArray::number(vector.z);
-}
-
 QString formatUsecTime(float usecs, int prec) {
     static const quint64 SECONDS_PER_MINUTE = 60;
     static const quint64 USECS_PER_MINUTE = USECS_PER_SECOND * SECONDS_PER_MINUTE;
diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h
index 18494d48e4..015758427a 100644
--- a/libraries/shared/src/SharedUtil.h
+++ b/libraries/shared/src/SharedUtil.h
@@ -19,9 +19,6 @@
 #include <unistd.h> // not on windows, not needed for mac or windows
 #endif
 
-#include <glm/glm.hpp>
-#include <glm/gtc/quaternion.hpp>
-
 #include <QtCore/QDebug>
 
 const int BYTES_PER_COLOR = 3;
@@ -71,8 +68,6 @@ float randomSign(); /// \return -1.0 or 1.0
 unsigned char randomColorValue(int minimum = 0);
 bool randomBoolean();
 
-glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float alpha);
-
 bool shouldDo(float desiredInterval, float deltaTime);
 
 void outputBufferBits(const unsigned char* buffer, int length, QDebug* continuedDebug = NULL);
@@ -108,8 +103,6 @@ int insertIntoSortedArrays(void* value, float key, int originalIndex,
 int removeFromSortedArrays(void* value, void** valueArray, float* keyArray, int* originalIndexArray,
                            int currentCount, int maxCount);
 
-
-
 // Helper Class for debugging
 class debug {
 public:
@@ -124,71 +117,9 @@ private:
 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
-// as possible. Taking advantage of the known characteristics of the semantic types.
-
-// 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 degrees);
-int unpackFloatAngleFromTwoByte(const uint16_t* byteAnglePointer, float* destinationPointer);
-
-// Orientation Quats are known to have 4 normalized components be between -1.0 and 1.0
-// this allows us to encode each component in 16bits with great accuracy
-int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput);
-int unpackOrientationQuatFromBytes(const unsigned char* buffer, glm::quat& quatOutput);
-
-// Ratios need the be highly accurate when less than 10, but not very accurate above 10, and they
-// are never greater than 1000 to 1, this allows us to encode each component in 16bits
-int packFloatRatioToTwoByte(unsigned char* buffer, float ratio);
-int unpackFloatRatioFromTwoByte(const unsigned char* buffer, float& ratio);
-
-// Near/Far Clip values need the be highly accurate when less than 10, but only integer accuracy above 10 and
-// they are never greater than 16,000, this allows us to encode each component in 16bits
-int packClipValueToTwoByte(unsigned char* buffer, float clipValue);
-int unpackClipValueFromTwoByte(const unsigned char* buffer, float& clipValue);
-
-// Positive floats that don't need to be very precise
-int packFloatToByte(unsigned char* buffer, float value, float scaleBy);
-int unpackFloatFromByte(const unsigned char* buffer, float& value, float scaleBy);
-
-// Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc
-int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix);
-int unpackFloatScalarFromSignedTwoByteFixed(const int16_t* byteFixedPointer, float* destinationPointer, int radix);
-
-// A convenience for sending vec3's as fixed-point floats
-int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix);
-int unpackFloatVec3FromSignedTwoByteFixed(const unsigned char* sourceBuffer, glm::vec3& destination, int radix);
-
-/// \return vec3 with euler angles in radians
-glm::vec3 safeEulerAngles(const glm::quat& q);
-
-float angleBetween(const glm::vec3& v1, const glm::vec3& v2); 
-
-glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2);
-
-glm::vec3 extractTranslation(const glm::mat4& matrix);
-
-void setTranslation(glm::mat4& matrix, const glm::vec3& translation);
-
-glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal = false);
-
-glm::vec3 extractScale(const glm::mat4& matrix);
-
-float extractUniformScale(const glm::mat4& matrix);
-
-float extractUniformScale(const glm::vec3& scale);
-
-/// \return bool are two orientations similar to each other
-const float ORIENTATION_SIMILAR_ENOUGH = 5.0f; // 10 degrees in any direction
-bool isSimilarOrientation(const glm::quat& orientionA, const glm::quat& orientionB, 
-                        float similarEnough = ORIENTATION_SIMILAR_ENOUGH);
-const float POSITION_SIMILAR_ENOUGH = 0.1f; // 0.1 meter
-bool isSimilarPosition(const glm::vec3& positionA, const glm::vec3& positionB, float similarEnough = POSITION_SIMILAR_ENOUGH);
-
 /// \return bool is the float NaN                        
 bool isNaN(float value);
 
-QByteArray createByteArray(const glm::vec3& vector);
-
 QString formatUsecTime(float usecs, int prec = 3);
 
 #endif // hifi_SharedUtil_h