Merge branch 'master' into feature/platform

This commit is contained in:
amerhifi 2019-05-13 15:39:55 -07:00
commit 9652d412ac
23 changed files with 320 additions and 70 deletions

View file

@ -62,7 +62,7 @@ endif()
# Use default time server if none defined in environment
set_from_env(TIMESERVER_URL TIMESERVER_URL "http://sha256timestamp.ws.symantec.com/sha256/timestamp")
set(HIFI_USE_OPTIMIZED_IK OFF)
set(HIFI_USE_OPTIMIZED_IK_OPTION OFF)
set(BUILD_CLIENT_OPTION ON)
set(BUILD_SERVER_OPTION ON)
set(BUILD_TESTS_OPTION OFF)
@ -126,7 +126,7 @@ if (USE_GLES AND (NOT ANDROID))
set(DISABLE_QML_OPTION ON)
endif()
option(HIFI_USE_OPTIMIZED_IK "USE OPTIMIZED IK" ${HIFI_USE_OPTIMIZED_IK_OPTION})
option(HIFI_USE_OPTIMIZED_IK "Use optimized IK" ${HIFI_USE_OPTIMIZED_IK_OPTION})
option(BUILD_CLIENT "Build client components" ${BUILD_CLIENT_OPTION})
option(BUILD_SERVER "Build server components" ${BUILD_SERVER_OPTION})
option(BUILD_TESTS "Build tests" ${BUILD_TESTS_OPTION})
@ -157,7 +157,7 @@ foreach(PLATFORM_QT_COMPONENT ${PLATFORM_QT_COMPONENTS})
list(APPEND PLATFORM_QT_LIBRARIES "Qt5::${PLATFORM_QT_COMPONENT}")
endforeach()
MESSAGE(STATUS "USE OPTIMIZED IK: " ${HIFI_USE_OPTIMIZED_IK})
MESSAGE(STATUS "Use optimized IK: " ${HIFI_USE_OPTIMIZED_IK})
MESSAGE(STATUS "Build server: " ${BUILD_SERVER})
MESSAGE(STATUS "Build client: " ${BUILD_CLIENT})
MESSAGE(STATUS "Build tests: " ${BUILD_TESTS})

View file

@ -985,6 +985,7 @@ const bool DEFAULT_PREFER_STYLUS_OVER_LASER = false;
const bool DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS = false;
const QString DEFAULT_CURSOR_NAME = "DEFAULT";
const bool DEFAULT_MINI_TABLET_ENABLED = true;
const bool DEFAULT_AWAY_STATE_WHEN_FOCUS_LOST_IN_VR_ENABLED = true;
QSharedPointer<OffscreenUi> getOffscreenUI() {
#if !defined(DISABLE_QML)
@ -1015,6 +1016,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
_preferStylusOverLaserSetting("preferStylusOverLaser", DEFAULT_PREFER_STYLUS_OVER_LASER),
_preferAvatarFingerOverStylusSetting("preferAvatarFingerOverStylus", DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS),
_constrainToolbarPosition("toolbar/constrainToolbarToCenterX", true),
_awayStateWhenFocusLostInVREnabled("awayStateWhenFocusLostInVREnabled", DEFAULT_AWAY_STATE_WHEN_FOCUS_LOST_IN_VR_ENABLED),
_preferredCursor("preferredCursor", DEFAULT_CURSOR_NAME),
_miniTabletEnabledSetting("miniTabletEnabled", DEFAULT_MINI_TABLET_ENABLED),
_scaleMirror(1.0f),
@ -3642,6 +3644,11 @@ void Application::setSettingConstrainToolbarPosition(bool setting) {
getOffscreenUI()->setConstrainToolbarToCenterX(setting);
}
void Application::setAwayStateWhenFocusLostInVREnabled(bool enabled) {
_awayStateWhenFocusLostInVREnabled.set(enabled);
emit awayStateWhenFocusLostInVRChanged(enabled);
}
void Application::setMiniTabletEnabled(bool enabled) {
_miniTabletEnabledSetting.set(enabled);
emit miniTabletEnabledChanged(enabled);

View file

@ -242,6 +242,9 @@ public:
float getSettingConstrainToolbarPosition() { return _constrainToolbarPosition.get(); }
void setSettingConstrainToolbarPosition(bool setting);
float getAwayStateWhenFocusLostInVREnabled() { return _awayStateWhenFocusLostInVREnabled.get(); }
void setAwayStateWhenFocusLostInVREnabled(bool setting);
Q_INVOKABLE void setMinimumGPUTextureMemStabilityCount(int stabilityCount) { _minimumGPUTextureMemSizeStabilityCount = stabilityCount; }
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
@ -372,6 +375,7 @@ signals:
void loginDialogFocusDisabled();
void miniTabletEnabledChanged(bool enabled);
void awayStateWhenFocusLostInVRChanged(bool enabled);
public slots:
QVector<EntityItemID> pasteEntities(float x, float y, float z);
@ -674,6 +678,7 @@ private:
Setting::Handle<bool> _preferStylusOverLaserSetting;
Setting::Handle<bool> _preferAvatarFingerOverStylusSetting;
Setting::Handle<bool> _constrainToolbarPosition;
Setting::Handle<bool> _awayStateWhenFocusLostInVREnabled;
Setting::Handle<QString> _preferredCursor;
Setting::Handle<bool> _miniTabletEnabledSetting;
Setting::Handle<bool> _keepLogWindowOnTop { "keepLogWindowOnTop", false };

View file

@ -20,6 +20,7 @@ class FancyCamera : public Camera {
/**jsdoc
* The <code>Camera</code> API provides access to the "camera" that defines your view in desktop and HMD display modes.
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, </code>-z</code> = forward.
*
* @namespace Camera
*

View file

@ -578,14 +578,20 @@ void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar
workload::SpacePointer space = _space;
transaction.transitionFinishedOperator(avatar->getRenderItemID(), [space, avatar]() {
const render::ScenePointer& scene = qApp->getMain3DScene();
render::Transaction transaction;
avatar->removeFromScene(avatar, scene, transaction);
scene->enqueueTransaction(transaction);
if (avatar->getLastFadeRequested() != render::Transition::Type::USER_LEAVE_DOMAIN) {
// The avatar is using another transition besides the fade-out transition, which means it is still in use.
// Deleting the avatar now could cause state issues, so abort deletion and show message.
qCWarning(interfaceapp) << "An ending fade-out transition wants to delete an avatar, but the avatar is still in use. Avatar deletion has aborted. (avatar ID: " << avatar->getSessionUUID() << ")";
} else {
const render::ScenePointer& scene = qApp->getMain3DScene();
render::Transaction transaction;
avatar->removeFromScene(avatar, scene, transaction);
scene->enqueueTransaction(transaction);
workload::Transaction workloadTransaction;
workloadTransaction.remove(avatar->getSpaceIndex());
space->enqueueTransaction(workloadTransaction);
workload::Transaction workloadTransaction;
workloadTransaction.remove(avatar->getSpaceIndex());
space->enqueueTransaction(workloadTransaction);
}
});
scene->enqueueTransaction(transaction);
}

View file

@ -3755,6 +3755,7 @@ void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettings
void MyAvatar::leaveDomain() {
clearScaleRestriction();
saveAvatarScale();
prepareResetTraitInstances();
}
void MyAvatar::saveAvatarScale() {

View file

@ -53,6 +53,15 @@ int main(int argc, const char* argv[]) {
// https://i.kym-cdn.com/entries/icons/original/000/008/342/ihave.jpg
QSurfaceFormat::setDefaultFormat(format);
#endif
#if defined(Q_OS_WIN)
// Check the minimum version of
if (gl::getAvailableVersion() < gl::getRequiredVersion()) {
MessageBoxA(nullptr, "Interface requires OpenGL 4.1 or higher", "Unsupported", MB_OK);
return -1;
}
#endif
setupHifiApplication(BuildInfo::INTERFACE_NAME);
QStringList arguments;

View file

@ -30,6 +30,9 @@ HMDScriptingInterface::HMDScriptingInterface() {
connect(qApp, &Application::miniTabletEnabledChanged, [this](bool enabled) {
emit miniTabletEnabledChanged(enabled);
});
connect(qApp, &Application::awayStateWhenFocusLostInVRChanged, [this](bool enabled) {
emit awayStateWhenFocusLostInVRChanged(enabled);
});
}
glm::vec3 HMDScriptingInterface::calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction) const {
@ -137,6 +140,14 @@ bool HMDScriptingInterface::getMiniTabletEnabled() {
return qApp->getMiniTabletEnabled();
}
void HMDScriptingInterface::setAwayStateWhenFocusLostInVREnabled(bool enabled) {
qApp->setAwayStateWhenFocusLostInVREnabled(enabled);
}
bool HMDScriptingInterface::getAwayStateWhenFocusLostInVREnabled() {
return qApp->getAwayStateWhenFocusLostInVREnabled();
}
QScriptValue HMDScriptingInterface::getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine) {
glm::vec3 hudIntersection;

View file

@ -375,6 +375,14 @@ signals:
*/
bool miniTabletEnabledChanged(bool enabled);
/**jsdoc
* Triggered when the altering the mode for going into an away state when the interface focus is lost in VR.
* @function HMD.awayStateWhenFocusLostInVRChanged
* @param {boolean} enabled - <code>true</code> if the setting to go into an away state in VR when the interface focus is lost is enabled, otherwise <code>false</code>.
* @returns {Signal}
*/
bool awayStateWhenFocusLostInVRChanged(bool enabled);
public:
HMDScriptingInterface();
@ -423,6 +431,9 @@ public:
void setMiniTabletEnabled(bool enabled);
bool getMiniTabletEnabled();
void setAwayStateWhenFocusLostInVREnabled(bool enabled);
bool getAwayStateWhenFocusLostInVREnabled();
QVariant getPlayAreaRect();
QVector<glm::vec3> getSensorPositions();

View file

@ -111,6 +111,12 @@ void setupPreferences() {
auto setter = [](bool value) { qApp->setSettingConstrainToolbarPosition(value); };
preferences->addPreference(new CheckPreference(UI_CATEGORY, "Constrain Toolbar Position to Horizontal Center", getter, setter));
}
{
auto getter = []()->bool { return qApp->getAwayStateWhenFocusLostInVREnabled(); };
auto setter = [](bool value) { qApp->setAwayStateWhenFocusLostInVREnabled(value); };
preferences->addPreference(new CheckPreference(UI_CATEGORY, "Go into away state when interface window loses focus in VR", getter, setter));
}
{
auto getter = []()->float { return qApp->getDesktopTabletScale(); };

View file

@ -690,6 +690,11 @@ void Avatar::fade(render::Transaction& transaction, render::Transition::Type typ
transaction.addTransitionToItem(itemId, type, _renderItemID);
}
}
_lastFadeRequested = type;
}
render::Transition::Type Avatar::getLastFadeRequested() const {
return _lastFadeRequested;
}
void Avatar::removeFromScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction) {

View file

@ -523,6 +523,7 @@ public:
void fadeIn(render::ScenePointer scene);
void fadeOut(render::Transaction& transaction, KillAvatarReason reason);
render::Transition::Type getLastFadeRequested() const;
// JSDoc is in AvatarData.h.
Q_INVOKABLE virtual float getEyeHeight() const override;
@ -701,6 +702,7 @@ protected:
virtual void updatePalms();
render::ItemID _renderItemID{ render::Item::INVALID_ITEM_ID };
render::Transition::Type _lastFadeRequested { render::Transition::Type::NONE }; // Used for sanity checking
ThreadSafeValueCache<glm::vec3> _leftPalmPositionCache { glm::vec3() };
ThreadSafeValueCache<glm::quat> _leftPalmRotationCache { glm::quat() };

View file

@ -71,19 +71,159 @@ void gl::globalRelease(bool finish) {}
#endif
void gl::getTargetVersion(int& major, int& minor) {
uint16_t gl::getTargetVersion() {
uint8_t major = 0, minor = 0;
#if defined(USE_GLES)
major = 3;
minor = 2;
#else
#if defined(Q_OS_MAC)
#elif defined(Q_OS_MAC)
major = 4;
minor = 1;
#else
major = 4;
minor = disableGl45() ? 1 : 5;
#endif
return GL_MAKE_VERSION(major, minor);
}
uint16_t gl::getRequiredVersion() {
uint8_t major = 0, minor = 0;
#if defined(USE_GLES)
major = 3;
minor = 2;
#else
major = 4;
minor = 1;
#endif
return GL_MAKE_VERSION(major, minor);
}
#if defined(Q_OS_WIN)
typedef BOOL(APIENTRYP PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hDC, HGLRC hShareContext, const int *attribList);
GLAPI PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
GLAPI PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
static bool setupPixelFormatSimple(HDC hdc) {
// FIXME build the PFD based on the
static const PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
24, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
1, // Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
24, // 24 Bit Z-Buffer (Depth Buffer)
8, // 8 Bit Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
auto pixelFormat = ChoosePixelFormat(hdc, &pfd);
if (pixelFormat == 0) {
return false;
}
if (SetPixelFormat(hdc, pixelFormat, &pfd) == FALSE) {
return false;
}
return true;
}
#endif
uint16_t gl::getAvailableVersion() {
static uint8_t major = 0, minor = 0;
static std::once_flag once;
std::call_once(once, [&] {
#if defined(USE_GLES)
// FIXME do runtime detection of the available GL version
major = 3;
minor = 2;
#elif defined(Q_OS_MAC)
// Damn it Apple.
major = 4;
minor = 1;
#elif defined(Q_OS_WIN)
//
HINSTANCE hInstance = GetModuleHandle(nullptr);
const auto windowClassName = "OpenGLVersionCheck";
WNDCLASS wc = { };
wc.lpfnWndProc = DefWindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = windowClassName;
RegisterClass(&wc);
using Handle = std::shared_ptr<void>;
HWND rawHwnd = CreateWindowEx(
WS_EX_APPWINDOW, // extended style
windowClassName, // class name
windowClassName, // title
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_OWNDC | WS_POPUP, // style
0, 0, 10, 10, // position and size
NULL, NULL, hInstance, NULL);
auto WindowDestroyer = [](void* handle) {
DestroyWindow((HWND)handle);
};
Handle hWnd = Handle(rawHwnd, WindowDestroyer);
if (!hWnd) {
return;
}
HDC rawDC = GetDC(rawHwnd);
auto DCDestroyer = [=](void* handle) {
ReleaseDC(rawHwnd, (HDC)handle);
};
if (!rawDC) {
return;
}
Handle hDC = Handle(rawDC, DCDestroyer);
if (!setupPixelFormatSimple(rawDC)) {
return;
}
auto GLRCDestroyer = [](void* handle) {
wglDeleteContext((HGLRC)handle);
};
auto rawglrc = wglCreateContext(rawDC);
if (!rawglrc) {
return;
}
Handle hGLRC = Handle(rawglrc, GLRCDestroyer);
if (!wglMakeCurrent(rawDC, rawglrc)) {
return;
}
gl::initModuleGl();
wglMakeCurrent(0, 0);
hGLRC.reset();
if (!wglChoosePixelFormatARB || !wglCreateContextAttribsARB) {
return;
}
// The only two versions we care about on Windows
// are 4.5 and 4.1
if (GLAD_GL_VERSION_4_5) {
major = 4;
minor = disableGl45() ? 1 : 5;
} else if (GLAD_GL_VERSION_4_1) {
major = 4;
minor = 1;
}
#else
// FIXME do runtime detection of GL version on non-Mac/Windows/Mobile platforms
major = 4;
minor = disableGl45() ? 1 : 5;
#endif
});
return GL_MAKE_VERSION(major, minor);
}
const QSurfaceFormat& getDefaultOpenGLSurfaceFormat() {
@ -105,10 +245,9 @@ const QSurfaceFormat& getDefaultOpenGLSurfaceFormat() {
// Qt Quick may need a depth and stencil buffer. Always make sure these are available.
format.setDepthBufferSize(DEFAULT_GL_DEPTH_BUFFER_BITS);
format.setStencilBufferSize(DEFAULT_GL_STENCIL_BUFFER_BITS);
int major, minor;
::gl::getTargetVersion(major, minor);
format.setMajorVersion(major);
format.setMinorVersion(minor);
auto glversion = ::gl::getTargetVersion();
format.setMajorVersion(GL_GET_MAJOR_VERSION(glversion));
format.setMinorVersion(GL_GET_MINOR_VERSION(glversion));
});
return format;
}

View file

@ -34,6 +34,10 @@ int glVersionToInteger(QString glVersion);
bool isRenderThread();
#define GL_MAKE_VERSION(major, minor) ((major << 8) | minor)
#define GL_GET_MINOR_VERSION(glversion) (glversion & 0x00FF)
#define GL_GET_MAJOR_VERSION(glversion) ((glversion & 0xFF00) >> 8)
namespace gl {
void globalLock();
void globalRelease(bool finish = true);
@ -52,7 +56,11 @@ namespace gl {
bool disableGl45();
void getTargetVersion(int& major, int& minor);
uint16_t getTargetVersion();
uint16_t getAvailableVersion();
uint16_t getRequiredVersion();
} // namespace gl
#define CHECK_GL_ERROR() ::gl::checkGLErrorDebug(__FUNCTION__)

View file

@ -61,7 +61,7 @@ void CalculateBlendshapeNormalsTask::run(const baker::BakeContextPointer& contex
outVertex = blendshape.vertices[lookupIndex];
} else {
// Index isn't in the blendshape, so return vertex from mesh
outVertex = mesh.vertices[lookupIndex];
outVertex = baker::safeGet(mesh.vertices, lookupIndex);
}
});
}

View file

@ -32,7 +32,7 @@ void CalculateMeshNormalsTask::run(const baker::BakeContextPointer& context, con
return &normalsOut[normalIndex];
},
[&mesh](int vertexIndex, glm::vec3& outVertex) /* VertexSetter */ {
outVertex = mesh.vertices[vertexIndex];
outVertex = baker::safeGet(mesh.vertices, vertexIndex);
}
);
}

View file

@ -25,6 +25,17 @@ namespace baker {
}
}
template<typename T>
const T& safeGet(const QVector<T>& data, int i) {
static T t;
if (i >= 0 && data.size() > i) {
return data[i];
} else {
return t;
}
}
// Returns a reference to the normal at the specified index, or nullptr if it cannot be accessed
using NormalAccessor = std::function<glm::vec3*(int index)>;

View file

@ -542,5 +542,3 @@ void GeometryResourceWatcher::resourceRefreshed() {
// FIXME: Model is not set up to handle a refresh
// _instance.reset();
}
#include "ModelCache.moc"

View file

@ -665,6 +665,8 @@ void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message)
// tell the domain handler that we're no longer connected so that below
// it can re-perform actions as if we just connected
_domainHandler.setIsConnected(false);
// Clear any reliable connections using old ID.
_nodeSocket.clearConnections();
}
setSessionLocalID(newLocalID);

View file

@ -23,7 +23,7 @@
#include <GLMHelpers.h>
/**jsdoc
* A quaternion value. See also the {@link Quat(0)|Quat} object.
* A quaternion value. See also the {@link Quat(0)|Quat} API.
* @typedef {object} Quat
* @property {number} x - Imaginary component i.
* @property {number} y - Imaginary component j.
@ -32,9 +32,10 @@
*/
/**jsdoc
* The Quat API provides facilities for generating and manipulating quaternions.
* The <code>Quat</code> API provides facilities for generating and manipulating quaternions.
* Quaternions should be used in preference to Euler angles wherever possible because quaternions don't suffer from the problem
* of gimbal lock.
*
* @namespace Quat
* @variation 0
*
@ -59,7 +60,7 @@ class Quat : public QObject, protected QScriptable {
public slots:
/**jsdoc
* Multiply two quaternions.
* Multiplies two quaternions.
* @function Quat(0).multiply
* @param {Quat} q1 - The first quaternion.
* @param {Quat} q2 - The second quaternion.
@ -90,8 +91,8 @@ public slots:
glm::quat normalize(const glm::quat& q);
/**jsdoc
* Calculate the conjugate of a quaternion. For a unit quaternion, its conjugate is the same as its
* {@link Quat(0).inverse|Quat.inverse}.
* Calculates the conjugate of a quaternion. For a unit quaternion, its conjugate is the same as its
* {@link Quat(0).inverse|Quat.inverse}.
* @function Quat(0).conjugate
* @param {Quat} q - The quaternion to conjugate.
* @returns {Quat} The conjugate of <code>q</code>.
@ -106,8 +107,9 @@ public slots:
glm::quat conjugate(const glm::quat& q);
/**jsdoc
* Calculate a camera orientation given eye position, point of interest, and "up" direction. The camera's negative z-axis is
* the forward direction. The result has zero roll about its forward direction with respect to the given "up" direction.
* Calculates a camera orientation given an eye position, point of interest, and "up" direction. The camera's negative
* z-axis is the forward direction. The result has zero roll about its forward direction with respect to the given "up"
* direction.
* @function Quat(0).lookAt
* @param {Vec3} eye - The eye position.
* @param {Vec3} target - The point to look at.
@ -121,7 +123,7 @@ public slots:
glm::quat lookAt(const glm::vec3& eye, const glm::vec3& center, const glm::vec3& up);
/**jsdoc
* Calculate a camera orientation given eye position and point of interest. The camera's negative z-axis is the forward
* Calculates a camera orientation given an eye position and point of interest. The camera's negative z-axis is the forward
* direction. The result has zero roll about its forward direction.
* @function Quat(0).lookAtSimple
* @param {Vec3} eye - The eye position.
@ -137,7 +139,7 @@ public slots:
glm::quat lookAtSimple(const glm::vec3& eye, const glm::vec3& center);
/**jsdoc
* Calculate the shortest rotation from a first vector onto a second.
* Calculates the shortest rotation from a first vector onto a second.
* @function Quat(0).rotationBetween
* @param {Vec3} v1 - The first vector.
* @param {Vec3} v2 - The second vector.
@ -154,7 +156,7 @@ public slots:
glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2);
/**jsdoc
* Generate a quaternion from a {@link Vec3} of Euler angles in degrees.
* Generates a quaternion from a {@link Vec3} of Euler angles in degrees.
* @function Quat(0).fromVec3Degrees
* @param {Vec3} vector - A vector of three Euler angles in degrees, the angles being the rotations about the x, y, and z
* axes.
@ -168,7 +170,7 @@ public slots:
glm::quat fromVec3Degrees(const glm::vec3& vec3);
/**jsdoc
* Generate a quaternion from a {@link Vec3} of Euler angles in radians.
* Generates a quaternion from a {@link Vec3} of Euler angles in radians.
* @function Quat(0).fromVec3Radians
* @param {Vec3} vector - A vector of three Euler angles in radians, the angles being the rotations about the x, y, and z
* axes.
@ -179,7 +181,7 @@ public slots:
glm::quat fromVec3Radians(const glm::vec3& vec3);
/**jsdoc
* Generate a quaternion from pitch, yaw, and roll values in degrees.
* Generates a quaternion from pitch, yaw, and roll values in degrees.
* @function Quat(0).fromPitchYawRollDegrees
* @param {number} pitch - The pitch angle in degrees.
* @param {number} yaw - The yaw angle in degrees.
@ -191,7 +193,7 @@ public slots:
glm::quat fromPitchYawRollDegrees(float pitch, float yaw, float roll);
/**jsdoc
* Generate a quaternion from pitch, yaw, and roll values in radians.
* Generates a quaternion from pitch, yaw, and roll values in radians.
* @function Quat(0).fromPitchYawRollRadians
* @param {number} pitch - The pitch angle in radians.
* @param {number} yaw - The yaw angle in radians.
@ -203,7 +205,7 @@ public slots:
glm::quat fromPitchYawRollRadians(float pitch, float yaw, float roll);
/**jsdoc
* Calculate the inverse of a quaternion. For a unit quaternion, its inverse is the same as its
* Calculates the inverse of a quaternion. For a unit quaternion, its inverse is the same as its
* {@link Quat(0).conjugate|Quat.conjugate}.
* @function Quat(0).inverse
* @param {Quat} q - The quaternion.
@ -219,9 +221,9 @@ public slots:
glm::quat inverse(const glm::quat& q);
/**jsdoc
* Get the "front" direction that the camera would face if its orientation was set to the quaternion value.
* Gets the "front" direction that the camera would face if its orientation was set to the quaternion value.
* This is a synonym for {@link Quat(0).getForward|Quat.getForward}.
* The High Fidelity camera has axes x = right, y = up, -z = forward.
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, </code>-z</code> = forward.
* @function Quat(0).getFront
* @param {Quat} orientation - A quaternion representing an orientation.
* @returns {Vec3} The negative z-axis rotated by <code>orientation</code>.
@ -229,9 +231,9 @@ public slots:
glm::vec3 getFront(const glm::quat& orientation) { return getForward(orientation); }
/**jsdoc
* Get the "forward" direction that the camera would face if its orientation was set to the quaternion value.
* Gets the "forward" direction that the camera would face if its orientation was set to the quaternion value.
* This is a synonym for {@link Quat(0).getFront|Quat.getFront}.
* The High Fidelity camera has axes x = right, y = up, -z = forward.
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, </code>-z</code> = forward.
* @function Quat(0).getForward
* @param {Quat} orientation - A quaternion representing an orientation.
* @returns {Vec3} The negative z-axis rotated by <code>orientation</code>.
@ -242,8 +244,8 @@ public slots:
glm::vec3 getForward(const glm::quat& orientation);
/**jsdoc
* Get the "right" direction that the camera would have if its orientation was set to the quaternion value.
* The High Fidelity camera has axes x = right, y = up, -z = forward.
* Gets the "right" direction that the camera would have if its orientation was set to the quaternion value.
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, </code>-z</code> = forward.
* @function Quat(0).getRight
* @param {Quat} orientation - A quaternion representing an orientation.
* @returns {Vec3} The x-axis rotated by <code>orientation</code>.
@ -251,8 +253,8 @@ public slots:
glm::vec3 getRight(const glm::quat& orientation);
/**jsdoc
* Get the "up" direction that the camera would have if its orientation was set to the quaternion value.
* The High Fidelity camera has axes x = right, y = up, -z = forward.
* Gets the "up" direction that the camera would have if its orientation was set to the quaternion value.
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, </code>-z</code> = forward.
* @function Quat(0).getUp
* @param {Quat} orientation - A quaternion representing an orientation.
* @returns {Vec3} The y-axis rotated by <code>orientation</code>.
@ -260,8 +262,8 @@ public slots:
glm::vec3 getUp(const glm::quat& orientation);
/**jsdoc
* Calculate the Euler angles for the quaternion, in degrees. (The "safe" in the name signifies that the angle results will
* not be garbage even when the rotation is particularly difficult to decompose with pitches around +/-90 degrees.)
* Calculates the Euler angles for the quaternion, in degrees. (The "safe" in the name signifies that the angle results
* will not be garbage even when the rotation is particularly difficult to decompose with pitches around +/-90 degrees.)
* @function Quat(0).safeEulerAngles
* @param {Quat} orientation - A quaternion representing an orientation.
* @returns {Vec3} A {@link Vec3} of Euler angles for the <code>orientation</code>, in degrees, the angles being the
@ -273,7 +275,7 @@ public slots:
glm::vec3 safeEulerAngles(const glm::quat& orientation);
/**jsdoc
* Generate a quaternion given an angle to rotate through and an axis to rotate about.
* Generates a quaternion given an angle to rotate through and an axis to rotate about.
* @function Quat(0).angleAxis
* @param {number} angle - The angle to rotate through, in degrees.
* @param {Vec3} axis - The unit axis to rotate about.
@ -286,7 +288,7 @@ public slots:
glm::quat angleAxis(float angle, const glm::vec3& v);
/**jsdoc
* Get the rotation axis for a quaternion.
* Gets the rotation axis for a quaternion.
* @function Quat(0).axis
* @param {Quat} q - The quaternion.
* @returns {Vec3} The normalized rotation axis for <code>q</code>.
@ -300,7 +302,7 @@ public slots:
glm::vec3 axis(const glm::quat& orientation);
/**jsdoc
* Get the rotation angle for a quaternion.
* Gets the rotation angle for a quaternion.
* @function Quat(0).angle
* @param {Quat} q - The quaternion.
* @returns {number} The rotation angle for <code>q</code>, in radians. <strong>WARNING:</strong> This value is in radians
@ -316,7 +318,7 @@ public slots:
// spherical linear interpolation
// alpha: 0.0 to 1.0?
/**jsdoc
* Compute a spherical linear interpolation between two rotations, safely handling two rotations that are very similar.
* Computes a spherical linear interpolation between two rotations, safely handling two rotations that are very similar.
* See also, {@link Quat(0).slerp|Quat.slerp}.
* @function Quat(0).mix
* @param {Quat} q1 - The beginning rotation.
@ -336,7 +338,7 @@ public slots:
glm::quat mix(const glm::quat& q1, const glm::quat& q2, float alpha);
/**jsdoc
* Compute a spherical linear interpolation between two rotations, for rotations that are not very similar.
* Computes a spherical linear interpolation between two rotations, for rotations that are not very similar.
* See also, {@link Quat(0).mix|Quat.mix}.
* @function Quat(0).slerp
* @param {Quat} q1 - The beginning rotation.
@ -349,7 +351,7 @@ public slots:
glm::quat slerp(const glm::quat& q1, const glm::quat& q2, float alpha);
/**jsdoc
* Compute a spherical quadrangle interpolation between two rotations along a path oriented toward two other rotations.
* Computes a spherical quadrangle interpolation between two rotations along a path oriented toward two other rotations.
* Equivalent to: <code>Quat.slerp(Quat.slerp(q1, q2, alpha), Quat.slerp(s1, s2, alpha), 2 * alpha * (1.0 - alpha))</code>.
* @function Quat(0).squad
* @param {Quat} q1 - Initial rotation.
@ -364,8 +366,8 @@ public slots:
glm::quat squad(const glm::quat& q1, const glm::quat& q2, const glm::quat& s1, const glm::quat& s2, float h);
/**jsdoc
* Calculate the dot product of two quaternions. The closer the quaternions are to each other the more non-zero the value is
* (either positive or negative). Identical unit rotations have a dot product of +/- 1.
* Calculates the dot product of two quaternions. The closer the quaternions are to each other the more non-zero the value
* is (either positive or negative). Identical unit rotations have a dot product of +/-1.
* @function Quat(0).dot
* @param {Quat} q1 - The first quaternion.
* @param {Quat} q2 - The second quaternion.
@ -385,7 +387,7 @@ public slots:
float dot(const glm::quat& q1, const glm::quat& q2);
/**jsdoc
* Print to the program log a text label followed by a quaternion's pitch, yaw, and roll Euler angles.
* Prints to the program log a text label followed by a quaternion's pitch, yaw, and roll Euler angles.
* @function Quat(0).print
* @param {string} label - The label to print.
* @param {Quat} q - The quaternion to print.
@ -403,7 +405,7 @@ public slots:
void print(const QString& label, const glm::quat& q, bool asDegrees = false);
/**jsdoc
* Test whether two quaternions are equal. <strong>Note:</strong> The quaternions must be exactly equal in order for
* Tests whether two quaternions are equal. <strong>Note:</strong> The quaternions must be exactly equal in order for
* <code>true</code> to be returned; it is often better to use {@link Quat(0).dot|Quat.dot} and test for closeness to +/-1.
* @function Quat(0).equal
* @param {Quat} q1 - The first quaternion.

View file

@ -366,17 +366,8 @@
"materialData": {
"tooltip": "Can be used instead of a JSON file when material set to materialData."
},
"materialNameToReplace": {
"tooltip": "Material name of parent entity to map this material entity on.",
"jsPropertyName": "parentMaterialName"
},
"submeshToReplace": {
"tooltip": "Submesh index of the parent entity to map this material on.",
"jsPropertyName": "parentMaterialName"
},
"selectSubmesh": {
"tooltip": "If enabled, \"Submesh to Replace\" property will show up, otherwise \"Material to Replace\" will be shown.",
"skipJSProperty": true
"parentMaterialName": {
"tooltip": "The target mesh indices or material names that this material entity should be assigned to on it's parent. This only supports parents that are Avatars as well as Shape or Model entity types."
},
"priority": {
"tooltip": "The priority of the material, where a larger number means higher priority. Original materials = 0."

View file

@ -67,6 +67,8 @@ var avatarPosition = MyAvatar.position;
var wasHmdMounted = HMD.mounted;
var previousBubbleState = Users.getIgnoreRadiusEnabled();
var enterAwayStateWhenFocusLostInVR = HMD.enterAwayStateWhenFocusLostInVR;
// some intervals we may create/delete
var avatarMovedInterval;
@ -283,8 +285,10 @@ function maybeGoAway() {
if (Reticle.mouseCaptured !== wasMouseCaptured) {
wasMouseCaptured = !wasMouseCaptured;
if (!wasMouseCaptured) {
goAway();
return;
if (enterAwayStateWhenFocusLostInVR) {
goAway();
return;
}
}
}
@ -357,9 +361,14 @@ eventMapping.from(Controller.Standard.Back).peek().to(goActive);
eventMapping.from(Controller.Standard.Start).peek().to(goActive);
Controller.enableMapping(eventMappingName);
function awayStateWhenFocusLostInVRChanged(enabled) {
enterAwayStateWhenFocusLostInVR = enabled;
}
Script.scriptEnding.connect(function () {
Script.clearInterval(maybeIntervalTimer);
goActive();
HMD.awayStateWhenFocusLostInVRChanged.disconnect(awayStateWhenFocusLostInVRChanged);
Controller.disableMapping(eventMappingName);
Controller.mousePressEvent.disconnect(goActive);
Controller.keyPressEvent.disconnect(maybeGoActive);
@ -367,6 +376,8 @@ Script.scriptEnding.connect(function () {
Messages.unsubscribe(CHANNEL_AWAY_ENABLE);
});
HMD.awayStateWhenFocusLostInVRChanged.connect(awayStateWhenFocusLostInVRChanged);
if (HMD.active && !HMD.mounted) {
print("Starting script, while HMD is active and not mounted...");
goAway(true);

View file

@ -10,17 +10,33 @@
#include <QtCore/QTimer>
#include <gl/Config.h>
#include <gl/GLWindow.h>
#include <gl/GLHelpers.h>
int main(int argc, char** argv) {
auto glversion = gl::getAvailableVersion();
auto major = GL_GET_MAJOR_VERSION(glversion);
auto minor = GL_GET_MINOR_VERSION(glversion);
if (glversion < GL_MAKE_VERSION(4, 1)) {
MessageBoxA(nullptr, "Interface requires OpenGL 4.1 or higher", "Unsupported", MB_OK);
return 0;
}
QGuiApplication app(argc, argv);
bool quitting = false;
// FIXME need to handle window closing message so that we can stop the timer
GLWindow* window = new GLWindow();
window->create();
window->show();
window->setSurfaceType(QSurface::OpenGLSurface);
window->setFormat(getDefaultOpenGLSurfaceFormat());
bool contextCreated = false;
QTimer* timer = new QTimer();
QObject::connect(timer, &QTimer::timeout, [&] {
if (quitting) {
return;
}
if (!contextCreated) {
window->createContext();
contextCreated = true;
@ -33,9 +49,17 @@ int main(int argc, char** argv) {
window->swapBuffers();
window->doneCurrent();
});
// FIXME need to handle window closing message so that we can stop the timer
QObject::connect(&app, &QCoreApplication::aboutToQuit, [&] {
quitting = true;
QObject::disconnect(timer, &QTimer::timeout, nullptr, nullptr);
timer->stop();
timer->deleteLater();
});
timer->setInterval(15);
timer->setSingleShot(false);
timer->start();
app.exec();
return 0;
}