Merge branch 'master' into hazeZone

This commit is contained in:
Nissim 2017-10-19 13:39:18 -07:00
commit 61fc45c6bf
83 changed files with 835 additions and 513 deletions

View file

@ -118,6 +118,7 @@ macro(AUTOSCRIBE_SHADER_LIB)
foreach(SHADER_FILE ${SHADER_SOURCE_FILES})
AUTOSCRIBE_SHADER(${SHADER_FILE} ${SHADER_INCLUDE_FILES})
file(TO_CMAKE_PATH "${AUTOSCRIBE_SHADER_RETURN}" AUTOSCRIBE_GENERATED_FILE)
set_property(SOURCE ${AUTOSCRIBE_GENERATED_FILE} PROPERTY SKIP_AUTOMOC ON)
list(APPEND AUTOSCRIBE_SHADER_SRC ${AUTOSCRIBE_GENERATED_FILE})
endforeach()
#message(${TARGET_NAME} ${AUTOSCRIBE_SHADER_SRC})

View file

@ -0,0 +1,20 @@
function(GENERATE_QRC)
set(oneValueArgs OUTPUT PREFIX PATH)
set(multiValueArgs GLOBS)
cmake_parse_arguments(GENERATE_QRC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
if ("${GENERATE_QRC_PREFIX}" STREQUAL "")
set(QRC_PREFIX_PATH /)
else()
set(QRC_PREFIX_PATH ${GENERATE_QRC_PREFIX})
endif()
foreach(GLOB ${GENERATE_QRC_GLOBS})
file(GLOB_RECURSE FOUND_FILES RELATIVE ${GENERATE_QRC_PATH} ${GLOB})
foreach(FILENAME ${FOUND_FILES})
set(QRC_CONTENTS "${QRC_CONTENTS}<file alias=\"${FILENAME}\">${GENERATE_QRC_PATH}/${FILENAME}</file>\n")
endforeach()
endforeach()
configure_file("${HF_CMAKE_DIR}/templates/resources.qrc.in" ${GENERATE_QRC_OUTPUT})
endfunction()

View file

@ -7,10 +7,12 @@
#
function(set_from_env _RESULT_NAME _ENV_VAR_NAME _DEFAULT_VALUE)
if ("$ENV{${_ENV_VAR_NAME}}" STREQUAL "")
set (${_RESULT_NAME} ${_DEFAULT_VALUE} PARENT_SCOPE)
else()
set (${_RESULT_NAME} $ENV{${_ENV_VAR_NAME}} PARENT_SCOPE)
if (NOT DEFINED ${_RESULT_NAME})
if ("$ENV{${_ENV_VAR_NAME}}" STREQUAL "")
set (${_RESULT_NAME} ${_DEFAULT_VALUE} PARENT_SCOPE)
else()
set (${_RESULT_NAME} $ENV{${_ENV_VAR_NAME}} PARENT_SCOPE)
endif()
endif()
endfunction()

View file

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="@QRC_PREFIX_PATH@">
@QRC_CONTENTS@
</qresource>
</RCC>

View file

@ -1,6 +1,20 @@
set(TARGET_NAME interface)
project(${TARGET_NAME})
file(GLOB_RECURSE QML_SRC resources/qml/*.qml resources/qml/*.js)
add_custom_target(qml SOURCES ${QML_SRC})
GroupSources("resources/qml")
function(JOIN VALUES GLUE OUTPUT)
string (REGEX REPLACE "([^\\]|^);" "\\1${GLUE}" _TMP_STR "${VALUES}")
string (REGEX REPLACE "[\\](.)" "\\1" _TMP_STR "${_TMP_STR}") #fixes escaping
set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
endfunction()
set(INTERFACE_QML_QRC ${CMAKE_CURRENT_BINARY_DIR}/qml.qrc)
generate_qrc(OUTPUT ${INTERFACE_QML_QRC} PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources GLOBS *.qml *.qss *.js *.html *.ttf *.gif *.svg *.png *.jpg)
# set a default root dir for each of our optional externals if it was not passed
set(OPTIONAL_EXTERNALS "LeapMotion")
@ -66,9 +80,7 @@ qt5_wrap_ui(QT_UI_HEADERS "${QT_UI_FILES}")
# add them to the interface source files
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${QT_UI_HEADERS}" "${QT_RESOURCES}")
file(GLOB_RECURSE QML_SRC resources/qml/*.qml resources/qml/*.js)
add_custom_target(qml SOURCES ${QML_SRC})
GroupSources("resources/qml")
list(APPEND INTERFACE_SRCS ${INTERFACE_QML_QRC})
if (UNIX)
install(
@ -131,10 +143,10 @@ if (APPLE)
# append the discovered resources to our list of interface sources
list(APPEND INTERFACE_SRCS ${DISCOVERED_RESOURCES})
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME}")
list(APPEND INTERFACE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME})
endif()
# create the executable, make it a bundle on OS X
if (APPLE)
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 KiB

After

Width:  |  Height:  |  Size: 604 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

After

Width:  |  Height:  |  Size: 503 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 KiB

After

Width:  |  Height:  |  Size: 585 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

After

Width:  |  Height:  |  Size: 547 KiB

View file

@ -18,7 +18,7 @@
function shouldRaiseKeyboard() {
var nodeName = document.activeElement.nodeName;
var nodeType = document.activeElement.type;
if (nodeName === "INPUT" && ["email", "number", "password", "tel", "text", "url"].indexOf(nodeType) !== -1
if (nodeName === "INPUT" && ["email", "number", "password", "tel", "text", "url", "search"].indexOf(nodeType) !== -1
|| document.activeElement.nodeName === "TEXTAREA") {
return true;
} else {

View file

@ -239,6 +239,25 @@ Rectangle {
}
}
}
}
HifiCommerceCommon.FirstUseTutorial {
id: firstUseTutorial;
z: 999;
visible: root.activeView === "firstUseTutorial";
anchors.fill: parent;
Connections {
onSendSignalToParent: {
switch (message.method) {
case 'tutorial_skipClicked':
case 'tutorial_finished':
Settings.setValue("isFirstUseOfPurchases", false);
root.activeView = "checkoutSuccess";
break;
}
}
}
}
//
@ -611,6 +630,28 @@ Rectangle {
lightboxPopup.visible = true;
}
}
RalewaySemiBold {
id: explainRezText;
//visible: !root.isWearable;
text: '<font color="' + hifi.colors.redAccent + '"><a href="#">What does "Rez" mean?</a></font>'
// Text size
size: 16;
// Anchors
anchors.top: noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom;
anchors.topMargin: 6;
height: paintedHeight;
anchors.left: parent.left;
anchors.right: parent.right;
// Style
color: hifi.colors.redAccent;
wrapMode: Text.WordWrap;
// Alignment
horizontalAlignment: Text.AlignHCenter;
verticalAlignment: Text.AlignVCenter;
onLinkActivated: {
root.activeView = "firstUseTutorial";
}
}
RalewaySemiBold {
id: myPurchasesLink;
@ -618,7 +659,7 @@ Rectangle {
// Text size
size: 20;
// Anchors
anchors.top: noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom;
anchors.top: explainRezText.visible ? explainRezText.bottom : (noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom);
anchors.topMargin: 40;
height: paintedHeight;
anchors.left: parent.left;

View file

@ -25,7 +25,13 @@ Rectangle {
HifiConstants { id: hifi; }
id: root;
property int activeView: 1;
property int activeView: 1;
onVisibleChanged: {
if (visible) {
root.activeView = 1;
}
}
Image {
anchors.fill: parent;

View file

@ -200,12 +200,6 @@ Rectangle {
// Style
color: hifi.colors.lightGray;
}
FontLoader { id: ralewayRegular; source: "../../../../fonts/Raleway-Regular.ttf"; }
TextMetrics {
id: textMetrics;
font.family: ralewayRegular.name
text: root.itemOwner;
}
RalewayRegular {
id: ownedBy;
text: root.itemOwner;
@ -215,8 +209,7 @@ Rectangle {
anchors.top: ownedByHeader.bottom;
anchors.topMargin: 8;
anchors.left: ownedByHeader.left;
height: textMetrics.height;
width: root.isMyCert ? textMetrics.width + 25 : ownedByHeader.width;
height: paintedHeight;
// Style
color: hifi.colors.darkGray;
elide: Text.ElideRight;
@ -231,7 +224,7 @@ Rectangle {
anchors.topMargin: 4;
anchors.bottom: ownedBy.bottom;
anchors.left: ownedBy.right;
anchors.leftMargin: 4;
anchors.leftMargin: 6;
anchors.right: ownedByHeader.right;
// Style
color: hifi.colors.lightGray;

View file

@ -241,7 +241,7 @@ Rectangle {
}
}
FirstUseTutorial {
HifiCommerceCommon.FirstUseTutorial {
id: firstUseTutorial;
z: 999;
visible: root.activeView === "firstUseTutorial";

View file

@ -25,6 +25,7 @@ Item {
id: root;
property string keyFilePath;
property bool showDebugButtons: true;
Hifi.QmlCommerce {
id: commerce;
@ -56,6 +57,7 @@ Item {
}
HifiControlsUit.Button {
id: clearCachedPassphraseButton;
visible: root.showDebugButtons;
color: hifi.buttons.black;
colorScheme: hifi.colorSchemes.dark;
anchors.top: parent.top;
@ -71,6 +73,7 @@ Item {
}
HifiControlsUit.Button {
id: resetButton;
visible: root.showDebugButtons;
color: hifi.buttons.red;
colorScheme: hifi.colorSchemes.dark;
anchors.top: clearCachedPassphraseButton.top;
@ -90,17 +93,22 @@ Item {
ListElement {
isExpanded: false;
question: "What are private keys?"
answer: qsTr("A private key is a secret piece of text that is used to decrypt code.<br><br>In High Fidelity, <b>your private keys are used to decrypt the contents of your Wallet and Purchases.</b>");
answer: qsTr("A private key is a secret piece of text that is used to prove ownership, unlock confidential information, and sign transactions.<br><br>In High Fidelity, <b>your private keys are used to securely access the contents of your Wallet and Purchases.</b>");
}
ListElement {
isExpanded: false;
question: "Where are my private keys stored?"
answer: qsTr('Your private keys are <b>only stored on your hard drive</b> in High Fidelity Interface\'s AppData directory.<br><br><b><font color="#0093C5"><a href="#privateKeyPath">Tap here to open the file path of your hifikey in your file explorer.</a></font></b><br><br> You may backup this file by copying it to a USB flash drive, or to a service like Dropbox or Google Drive. Restore your backup by replacing the file in Interface\'s AppData directory with your backed-up copy.');
answer: qsTr('By default, your private keys are <b>only stored on your hard drive</b> in High Fidelity Interface\'s AppData directory.<br><br><b><font color="#0093C5"><a href="#privateKeyPath">Tap here to open the folder where your HifiKeys are stored on your main display.</a></font></b>');
}
ListElement {
isExpanded: false;
question: "How can I backup my private keys?"
answer: qsTr('You may backup the file containing your private keys by copying it to a USB flash drive, or to a service like Dropbox or Google Drive.<br><br>Restore your backup by replacing the file in Interface\'s AppData directory with your backed-up copy.<br><br><b><font color="#0093C5"><a href="#privateKeyPath">Tap here to open the folder where your HifiKeys are stored on your main display.</a></font></b>');
}
ListElement {
isExpanded: false;
question: "What happens if I lose my passphrase?"
answer: qsTr("If you lose your passphrase, you will no longer have access to the contents of your Wallet or My Purchases.<br><br><b>Nobody can help you recover your passphrase, including High Fidelity.</b> Please write it down and store it securely.");
answer: qsTr("Your passphrase is used to encrypt your private keys. If you lose your passphrase, you will no longer be able to decrypt your private key file. You will also no longer have access to the contents of your Wallet or My Purchases.<br><br><b>Nobody can help you recover your passphrase, including High Fidelity.</b> Please write it down and store it securely.");
}
ListElement {
isExpanded: false;

View file

@ -25,7 +25,7 @@ Item {
HifiConstants { id: hifi; }
id: root;
z: 998;
z: 997;
property bool keyboardRaised: false;
property string titleBarIcon: "";
property string titleBarText: "";
@ -350,7 +350,7 @@ Item {
Item {
id: keyboardContainer;
z: 999;
z: 998;
visible: keyboard.raised;
property bool punctuationMode: false;
anchors {
@ -361,11 +361,13 @@ Item {
Image {
id: lowerKeyboardButton;
z: 999;
source: "images/lowerKeyboard.png";
anchors.horizontalCenter: parent.horizontalCenter;
anchors.bottom: keyboard.top;
height: 30;
width: 120;
anchors.right: keyboard.right;
anchors.top: keyboard.showMirrorText ? keyboard.top : undefined;
anchors.bottom: keyboard.showMirrorText ? undefined : keyboard.bottom;
height: 50;
width: 60;
MouseArea {
anchors.fill: parent;

View file

@ -290,7 +290,17 @@ Item {
id: removeHmdContainer;
z: 998;
visible: false;
color: hifi.colors.blueHighlight;
gradient: Gradient {
GradientStop {
position: 0.2;
color: hifi.colors.baseGrayHighlight;
}
GradientStop {
position: 1.0;
color: hifi.colors.baseGrayShadow;
}
}
anchors.fill: backupInstructionsButton;
radius: 5;
MouseArea {

View file

@ -165,7 +165,7 @@ Rectangle {
WalletSetup {
id: walletSetup;
visible: root.activeView === "walletSetup";
z: 998;
z: 997;
anchors.fill: parent;
Connections {
@ -192,7 +192,7 @@ Rectangle {
PassphraseChange {
id: passphraseChange;
visible: root.activeView === "passphraseChange";
z: 998;
z: 997;
anchors.top: titleBarContainer.bottom;
anchors.left: parent.left;
anchors.right: parent.right;
@ -217,7 +217,7 @@ Rectangle {
SecurityImageChange {
id: securityImageChange;
visible: root.activeView === "securityImageChange";
z: 998;
z: 997;
anchors.top: titleBarContainer.bottom;
anchors.left: parent.left;
anchors.right: parent.right;
@ -653,7 +653,7 @@ Rectangle {
Item {
id: keyboardContainer;
z: 999;
z: 998;
visible: keyboard.raised;
property bool punctuationMode: false;
anchors {
@ -664,11 +664,13 @@ Rectangle {
Image {
id: lowerKeyboardButton;
z: 999;
source: "images/lowerKeyboard.png";
anchors.horizontalCenter: parent.horizontalCenter;
anchors.bottom: keyboard.top;
height: 30;
width: 120;
anchors.right: keyboard.right;
anchors.top: keyboard.showMirrorText ? keyboard.top : undefined;
anchors.bottom: keyboard.showMirrorText ? undefined : keyboard.bottom;
height: 50;
width: 60;
MouseArea {
anchors.fill: parent;

View file

@ -164,7 +164,7 @@ Item {
anchors.top: parent.top;
anchors.topMargin: 26;
anchors.left: parent.left;
anchors.leftMargin: 30;
anchors.leftMargin: 20;
anchors.right: parent.right;
anchors.rightMargin: 30;
height: 30;

View file

@ -679,7 +679,7 @@ Item {
anchors.right: parent.right;
anchors.rightMargin: 30;
height: 40;
text: "Open Instructions for Later";
text: "Open Backup Instructions for Later";
onClicked: {
instructions01Container.visible = false;
instructions02Container.visible = true;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -19,6 +19,7 @@ Window {
shown: true
width: content.width
height: content.height
disableFade: true
// Disable this window from being able to call 'desktop.raise() and desktop.showDesktop'
activator: Item {}
property bool horizontal: true

View file

@ -26,6 +26,7 @@ FocusScope {
property var completionCallback;
// The target property to animate, usually scale or opacity
property alias fadeTargetProperty: root.opacity
property bool disableFade: false
// always start the property at 0 to enable fade in on creation
fadeTargetProperty: 0
// DO NOT set visible to false or when derived types override it it
@ -35,6 +36,9 @@ FocusScope {
// Some dialogs should be destroyed when they become
// invisible, so handle that
onVisibleChanged: {
if (disableFade) {
return;
}
// If someone directly set the visibility to false
// toggle it back on and use the targetVisible flag to transition
// via fading.
@ -62,7 +66,9 @@ FocusScope {
}
onFadeTargetPropertyChanged: {
visible = (fadeTargetProperty != 0.0);
if (!disableFade) {
visible = (fadeTargetProperty != 0.0);
}
}
function fadeIn(callback) {

View file

@ -2255,7 +2255,7 @@ void Application::initializeUi() {
offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
// support the window management and scripting proxies for VR use
offscreenUi->createDesktop(QString("hifi/Desktop.qml"));
offscreenUi->createDesktop(QString("qrc:///qml/hifi/Desktop.qml"));
// FIXME either expose so that dialogs can set this themselves or
// do better detection in the offscreen UI of what has focus

View file

@ -16,6 +16,8 @@
#include <glm/glm.hpp>
#include <QUuid>
#include <SettingHandle.h>
#include <Rig.h>
#include <Sound.h>
@ -106,6 +108,8 @@ class MyAvatar : public Avatar {
* "scripts/system/controllers/toggleAdvancedMovementForHandControllers.js".
* @property userHeight {number} The height of the user in sensor space. (meters).
* @property userEyeHeight {number} Estimated height of the users eyes in sensor space. (meters)
* @property SELF_ID {string} READ-ONLY. UUID representing "my avatar". Only use for local-only entities and overlays in situations where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain).
* Note: Likely to be deprecated.
*/
// FIXME: `glm::vec3 position` is not accessible from QML, so this exposes position in a QML-native type
@ -152,6 +156,8 @@ class MyAvatar : public Avatar {
Q_PROPERTY(float userHeight READ getUserHeight WRITE setUserHeight)
Q_PROPERTY(float userEyeHeight READ getUserEyeHeight)
Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT)
const QString DOMINANT_LEFT_HAND = "left";
const QString DOMINANT_RIGHT_HAND = "right";
@ -546,6 +552,8 @@ public:
virtual SpatialParentTree* getParentTree() const override;
const QUuid& getSelfID() const { return AVATAR_SELF_ID; }
public slots:
void increaseSize();
void decreaseSize();
@ -648,8 +656,6 @@ private:
void setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visiblity);
private:
virtual void updatePalms() override {}
void lateUpdatePalms();

View file

@ -105,19 +105,19 @@ RSA* readKeys(const char* filename) {
return key;
}
bool writeBackupInstructions() {
bool Wallet::writeBackupInstructions() {
QString inputFilename(PathUtils::resourcesPath() + "html/commerce/backup_instructions.html");
QString filename = PathUtils::getAppDataFilePath(INSTRUCTIONS_FILE);
QFile outputFile(filename);
QString outputFilename = PathUtils::getAppDataFilePath(INSTRUCTIONS_FILE);
QFile outputFile(outputFilename);
bool retval = false;
if (QFile::exists(filename))
if (QFile::exists(outputFilename) || getKeyFilePath() == "")
{
QFile::remove(filename);
return false;
}
QFile::copy(inputFilename, filename);
QFile::copy(inputFilename, outputFilename);
if (QFile::exists(filename) && outputFile.open(QIODevice::ReadWrite)) {
if (QFile::exists(outputFilename) && outputFile.open(QIODevice::ReadWrite)) {
QByteArray fileData = outputFile.readAll();
QString text(fileData);
@ -132,7 +132,7 @@ bool writeBackupInstructions() {
retval = true;
qCDebug(commerce) << "wrote html file successfully";
} else {
qCDebug(commerce) << "failed to open output html file" << filename;
qCDebug(commerce) << "failed to open output html file" << outputFilename;
}
return retval;
}
@ -154,8 +154,6 @@ bool writeKeys(const char* filename, RSA* keys) {
QFile(QString(filename)).remove();
return retval;
}
writeBackupInstructions();
retval = true;
qCDebug(commerce) << "wrote keys successfully";
@ -359,6 +357,8 @@ bool Wallet::setPassphrase(const QString& passphrase) {
_publicKeys.clear();
writeBackupInstructions();
return true;
}
@ -526,6 +526,8 @@ bool Wallet::generateKeyPair() {
qCInfo(commerce) << "Generating keypair.";
auto keyPair = generateRSAKeypair();
writeBackupInstructions();
// TODO: redo this soon -- need error checking and so on
writeSecurityImage(_securityImage, keyFilePath());
QString oldKey = _publicKeys.count() == 0 ? "" : _publicKeys.last();

View file

@ -80,6 +80,7 @@ private:
void updateImageProvider();
bool writeSecurityImage(const QPixmap* pixmap, const QString& outputFilePath);
bool readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen);
bool writeBackupInstructions();
bool verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText);

View file

@ -15,13 +15,14 @@
#include "avatar/AvatarManager.h"
LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates,
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) :
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled) :
_renderingEnabled(enabled),
_renderStates(renderStates),
_defaultRenderStates(defaultRenderStates),
_faceAvatar(faceAvatar),
_centerEndY(centerEndY),
_lockEnd(lockEnd)
_lockEnd(lockEnd),
_distanceScaleEnd(distanceScaleEnd)
{
_rayPickUID = DependencyManager::get<RayPickScriptingInterface>()->createRayPick(rayProps);
@ -86,6 +87,10 @@ void LaserPointer::editRenderState(const std::string& state, const QVariant& sta
updateRenderStateOverlay(_renderStates[state].getStartID(), startProps);
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
QVariant endDim = endProps.toMap()["dimensions"];
if (endDim.isValid()) {
_renderStates[state].setEndDim(vec3FromVariant(endDim));
}
}
void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& props) {
@ -154,10 +159,14 @@ void LaserPointer::updateRenderState(const RenderState& renderState, const Inter
if (!renderState.getEndID().isNull()) {
QVariantMap endProps;
glm::quat faceAvatarRotation = DependencyManager::get<AvatarManager>()->getMyAvatar()->getOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, 180.0f, 0.0f)));
glm::vec3 dim = vec3FromVariant(qApp->getOverlays().getProperty(renderState.getEndID(), "dimensions").value);
if (_distanceScaleEnd) {
dim = renderState.getEndDim() * glm::distance(pickRay.origin, endVec) * DependencyManager::get<AvatarManager>()->getMyAvatar()->getSensorToWorldScale();
endProps.insert("dimensions", vec3toVariant(dim));
}
if (_centerEndY) {
endProps.insert("position", end);
} else {
glm::vec3 dim = vec3FromVariant(qApp->getOverlays().getProperty(renderState.getEndID(), "dimensions").value);
glm::vec3 currentUpVector = faceAvatarRotation * Vectors::UP;
endProps.insert("position", vec3toVariant(endVec + glm::vec3(currentUpVector.x * 0.5f * dim.y, currentUpVector.y * 0.5f * dim.y, currentUpVector.z * 0.5f * dim.y)));
}
@ -264,6 +273,7 @@ RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, cons
_pathIgnoreRays = qApp->getOverlays().getProperty(_pathID, "ignoreRayIntersection").value.toBool();
}
if (!_endID.isNull()) {
_endDim = vec3FromVariant(qApp->getOverlays().getProperty(_endID, "dimensions").value);
_endIgnoreRays = qApp->getOverlays().getProperty(_endID, "ignoreRayIntersection").value.toBool();
}
}

View file

@ -32,6 +32,9 @@ public:
const bool& doesPathIgnoreRays() const { return _pathIgnoreRays; }
const bool& doesEndIgnoreRays() const { return _endIgnoreRays; }
void setEndDim(const glm::vec3& endDim) { _endDim = endDim; }
const glm::vec3& getEndDim() const { return _endDim; }
void deleteOverlays();
private:
@ -41,6 +44,8 @@ private:
bool _startIgnoreRays;
bool _pathIgnoreRays;
bool _endIgnoreRays;
glm::vec3 _endDim;
};
@ -52,7 +57,7 @@ public:
typedef std::unordered_map<std::string, std::pair<float, RenderState>> DefaultRenderStateMap;
LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates,
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled);
~LaserPointer();
QUuid getRayUID() { return _rayPickUID; }
@ -88,6 +93,7 @@ private:
bool _faceAvatar;
bool _centerEndY;
bool _lockEnd;
bool _distanceScaleEnd;
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
QUuid _rayPickUID;

View file

@ -11,8 +11,8 @@
#include "LaserPointerManager.h"
QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled);
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled) {
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled);
if (!laserPointer->getRayUID().isNull()) {
QWriteLocker containsLock(&_containsLock);
QUuid id = QUuid::createUuid();

View file

@ -22,7 +22,7 @@ class LaserPointerManager {
public:
QUuid createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled);
void removeLaserPointer(const QUuid uid);
void enableLaserPointer(const QUuid uid);
void disableLaserPointer(const QUuid uid);

View file

@ -32,6 +32,11 @@ QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& propert
lockEnd = propertyMap["lockEnd"].toBool();
}
bool distanceScaleEnd = false;
if (propertyMap["distanceScaleEnd"].isValid()) {
distanceScaleEnd = propertyMap["distanceScaleEnd"].toBool();
}
bool enabled = false;
if (propertyMap["enabled"].isValid()) {
enabled = propertyMap["enabled"].toBool();
@ -66,7 +71,7 @@ QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& propert
}
}
return qApp->getLaserPointerManager().createLaserPointer(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled);
return qApp->getLaserPointerManager().createLaserPointer(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled);
}
void LaserPointerScriptingInterface::editRenderState(QUuid uid, const QString& renderState, const QVariant& properties) {

View file

@ -994,10 +994,12 @@ glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const {
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
return glmExtractRotation(finalMat);
}
case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX:
case CONTROLLER_LEFTHAND_INDEX: {
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
return controllerLeftHandTransform.getRotation();
}
case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX:
case CONTROLLER_RIGHTHAND_INDEX: {
Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix());
return controllerRightHandTransform.getRotation();
@ -1032,10 +1034,12 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const {
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
return extractTranslation(finalMat);
}
case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX:
case CONTROLLER_LEFTHAND_INDEX: {
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
return controllerLeftHandTransform.getTranslation();
}
case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX:
case CONTROLLER_RIGHTHAND_INDEX: {
Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix());
return controllerRightHandTransform.getTranslation();

View file

@ -96,6 +96,7 @@ PolyLineEntityRenderer::PolyLineEntityRenderer(const EntityItemPointer& entity)
polylineFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, position));
polylineFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, normal));
polylineFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), offsetof(Vertex, uv));
polylineFormat->setAttribute(gpu::Stream::COLOR, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB), offsetof(Vertex, color));
});
PolyLineUniforms uniforms;
@ -116,7 +117,8 @@ bool PolyLineEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP
entity->pointsChanged() ||
entity->strokeWidthsChanged() ||
entity->normalsChanged() ||
entity->texturesChanged()
entity->texturesChanged() ||
entity->strokeColorsChanged()
);
}
@ -129,9 +131,11 @@ void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer&
if (!textures.isEmpty()) {
entityTextures = QUrl(textures);
}
_texture = DependencyManager::get<TextureCache>()->getTexture(entityTextures);
}
if (!_texture || _texture->getURL() != entityTextures) {
if (!_texture) {
_texture = DependencyManager::get<TextureCache>()->getTexture(entityTextures);
}
}
@ -143,6 +147,10 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
auto pointsChanged = entity->pointsChanged();
auto strokeWidthsChanged = entity->strokeWidthsChanged();
auto normalsChanged = entity->normalsChanged();
auto strokeColorsChanged = entity->strokeColorsChanged();
bool isUVModeStretch = entity->getIsUVModeStretch();
entity->resetPolyLineChanged();
_polylineTransform = Transform();
@ -158,10 +166,14 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
if (normalsChanged) {
_lastNormals = entity->getNormals();
}
if (pointsChanged || strokeWidthsChanged || normalsChanged) {
if (strokeColorsChanged) {
_lastStrokeColors = entity->getStrokeColors();
_lastStrokeColors = _lastNormals.size() == _lastStrokeColors.size() ? _lastStrokeColors : QVector<glm::vec3>({ toGlm(entity->getXColor()) });
}
if (pointsChanged || strokeWidthsChanged || normalsChanged || strokeColorsChanged) {
_empty = std::min(_lastPoints.size(), std::min(_lastNormals.size(), _lastStrokeWidths.size())) < 2;
if (!_empty) {
updateGeometry(updateVertices(_lastPoints, _lastNormals, _lastStrokeWidths));
updateGeometry(updateVertices(_lastPoints, _lastNormals, _lastStrokeWidths, _lastStrokeColors, isUVModeStretch, _textureAspectRatio));
}
}
}
@ -175,7 +187,12 @@ void PolyLineEntityRenderer::updateGeometry(const std::vector<Vertex>& vertices)
_verticesBuffer->setSubData(0, vertices);
}
std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertices(const QVector<glm::vec3>& points, const QVector<glm::vec3>& normals, const QVector<float>& strokeWidths) {
std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertices(const QVector<glm::vec3>& points,
const QVector<glm::vec3>& normals,
const QVector<float>& strokeWidths,
const QVector<glm::vec3>& strokeColors,
const bool isUVModeStretch,
const float textureAspectRatio) {
// Calculate the minimum vector size out of normals, points, and stroke widths
int size = std::min(points.size(), std::min(normals.size(), strokeWidths.size()));
@ -190,10 +207,52 @@ std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertic
float uCoord = 0.0f;
int finalIndex = size - 1;
glm::vec3 binormal;
float accumulatedDistance = 0.0f;
float distanceToLastPoint = 0.0f;
float accumulatedStrokeWidth = 0.0f;
float strokeWidth = 0.0f;
bool doesStrokeWidthVary = false;
for (int i = 1; i < strokeWidths.size(); i++) {
if (strokeWidths[i] != strokeWidths[i - 1]) {
doesStrokeWidthVary = true;
break;
}
}
for (int i = 0; i <= finalIndex; i++) {
const float& width = strokeWidths.at(i);
const auto& point = points.at(i);
const auto& normal = normals.at(i);
const auto& color = strokeColors.size() == normals.size() ? strokeColors.at(i) : strokeColors.at(0);
int vertexIndex = i * 2;
if (!isUVModeStretch && i >= 1) {
distanceToLastPoint = glm::distance(points.at(i), points.at(i - 1));
accumulatedDistance += distanceToLastPoint;
strokeWidth = 2 * strokeWidths[i];
if (doesStrokeWidthVary) {
//If the stroke varies along the line the texture will stretch more or less depending on the speed
//because it looks better than using the same method as below
accumulatedStrokeWidth += strokeWidth;
float increaseValue = 1;
if (accumulatedStrokeWidth != 0) {
float newUcoord = glm::ceil(((1.0f / textureAspectRatio) * accumulatedDistance) / (accumulatedStrokeWidth / i));
increaseValue = newUcoord - uCoord;
}
increaseValue = increaseValue > 0 ? increaseValue : 1;
uCoord += increaseValue;
} else {
//If the stroke width is constant then the textures should keep the aspect ratio along the line
uCoord = ((1.0f / textureAspectRatio) * accumulatedDistance) / strokeWidth;
}
} else if (vertexIndex >= 2) {
uCoord += uCoordInc;
}
// For last point we can assume binormals are the same since it represents the last two vertices of quad
if (i < finalIndex) {
@ -206,11 +265,10 @@ std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertic
}
}
const auto v1 = point + binormal;
const auto v2 = point - binormal;
vertices.emplace_back(v1, normal, vec2(uCoord, 0.0f));
vertices.emplace_back(v2, normal, vec2(uCoord, 1.0f));
uCoord += uCoordInc;
const auto v1 = points.at(i) + binormal;
const auto v2 = points.at(i) - binormal;
vertices.emplace_back(v1, normal, vec2(uCoord, 0.0f), color);
vertices.emplace_back(v2, normal, vec2(uCoord, 1.0f), color);
}
return vertices;
@ -235,6 +293,12 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, DependencyManager::get<TextureCache>()->getWhiteTexture());
}
float textureWidth = (float)_texture->getOriginalWidth();
float textureHeight = (float)_texture->getOriginalHeight();
if (textureWidth != 0 && textureHeight != 0) {
_textureAspectRatio = textureWidth / textureHeight;
}
batch.setInputFormat(polylineFormat);
batch.setInputBuffer(0, _verticesBuffer, 0, sizeof(Vertex));
@ -247,4 +311,4 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
#endif
batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0);
}
}

View file

@ -27,7 +27,9 @@ public:
protected:
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene,
Transaction& transaction,
const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual ItemKey getKey() override;
@ -38,24 +40,37 @@ protected:
struct Vertex {
Vertex() {}
Vertex(const vec3& position, const vec3& normal, const vec2& uv) : position(position), normal(normal), uv(uv) {}
Vertex(const vec3& position, const vec3& normal, const vec2& uv, const vec3& color) : position(position),
normal(normal),
uv(uv),
color(color) {}
vec3 position;
vec3 normal;
vec2 uv;
vec3 color;
};
void updateGeometry(const std::vector<Vertex>& vertices);
static std::vector<Vertex> updateVertices(const QVector<glm::vec3>& points, const QVector<glm::vec3>& normals, const QVector<float>& strokeWidths);
static std::vector<Vertex> updateVertices(const QVector<glm::vec3>& points,
const QVector<glm::vec3>& normals,
const QVector<float>& strokeWidths,
const QVector<glm::vec3>& strokeColors,
const bool isUVModeStretch,
const float textureAspectRatio);
Transform _polylineTransform;
QVector<glm::vec3> _lastPoints;
QVector<glm::vec3> _lastNormals;
QVector<glm::vec3> _lastStrokeColors;
QVector<float> _lastStrokeWidths;
gpu::BufferPointer _verticesBuffer;
gpu::BufferView _uniformBuffer;
uint32_t _numVertices { 0 };
bool _empty{ true };
NetworkTexturePointer _texture;
float _textureAspectRatio { 1.0f };
};
} } // namespace

View file

@ -40,7 +40,7 @@ void main(void) {
packDeferredFragmentTranslucent(
float(frontCondition) * interpolatedNormal,
texel.a * varColor.a,
polyline.color * texel.rgb,
color * texel.rgb,
vec3(0.01, 0.01, 0.01),
10.0);
}

View file

@ -355,7 +355,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_FACE_CAMERA, faceCamera);
CHECK_PROPERTY_CHANGE(PROP_ACTION_DATA, actionData);
CHECK_PROPERTY_CHANGE(PROP_NORMALS, normals);
CHECK_PROPERTY_CHANGE(PROP_STROKE_COLORS, strokeColors);
CHECK_PROPERTY_CHANGE(PROP_STROKE_WIDTHS, strokeWidths);
CHECK_PROPERTY_CHANGE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch);
CHECK_PROPERTY_CHANGE(PROP_X_TEXTURE_URL, xTextureURL);
CHECK_PROPERTY_CHANGE(PROP_Y_TEXTURE_URL, yTextureURL);
CHECK_PROPERTY_CHANGE(PROP_Z_TEXTURE_URL, zTextureURL);
@ -605,8 +607,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_WIDTH, lineWidth);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NORMALS, normals);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_COLORS, strokeColors);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch);
}
if (!skipDefaults && !strictSemantics) {
@ -771,7 +775,10 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
COPY_PROPERTY_FROM_QSCRIPTVALUE(faceCamera, bool, setFaceCamera);
COPY_PROPERTY_FROM_QSCRIPTVALUE(actionData, QByteArray, setActionData);
COPY_PROPERTY_FROM_QSCRIPTVALUE(normals, qVectorVec3, setNormals);
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeColors, qVectorVec3, setStrokeColors);
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeWidths,qVectorFloat, setStrokeWidths);
COPY_PROPERTY_FROM_QSCRIPTVALUE(isUVModeStretch, bool, setIsUVModeStretch);
if (!honorReadOnly) {
// this is used by the json reader to set things that we don't want javascript to able to affect.
@ -925,7 +932,9 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
COPY_PROPERTY_IF_CHANGED(faceCamera);
COPY_PROPERTY_IF_CHANGED(actionData);
COPY_PROPERTY_IF_CHANGED(normals);
COPY_PROPERTY_IF_CHANGED(strokeColors);
COPY_PROPERTY_IF_CHANGED(strokeWidths);
COPY_PROPERTY_IF_CHANGED(isUVModeStretch);
COPY_PROPERTY_IF_CHANGED(created);
_animation.merge(other._animation);
@ -1112,7 +1121,9 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
ADD_PROPERTY_TO_MAP(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
ADD_PROPERTY_TO_MAP(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
ADD_PROPERTY_TO_MAP(PROP_NORMALS, Normals, normals, QVector<glm::vec3>);
ADD_PROPERTY_TO_MAP(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector<glm::vec3>);
ADD_PROPERTY_TO_MAP(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>);
ADD_PROPERTY_TO_MAP(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, QVector<float>);
ADD_PROPERTY_TO_MAP(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
ADD_PROPERTY_TO_MAP(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
ADD_PROPERTY_TO_MAP(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString);
@ -1458,9 +1469,11 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
if (properties.getType() == EntityTypes::PolyLine) {
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth());
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getNormals());
APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getPackedNormals());
APPEND_ENTITY_PROPERTY(PROP_STROKE_COLORS, properties.getPackedStrokeColors());
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths());
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures());
APPEND_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, properties.getIsUVModeStretch());
}
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
// when encoding/decoding edits because otherwise they can't polymorph to other shape types
@ -1547,6 +1560,44 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
return success;
}
QByteArray EntityItemProperties::getPackedNormals() const {
return packNormals(getNormals());
}
QByteArray EntityItemProperties::packNormals(const QVector<glm::vec3>& normals) const {
int normalsSize = normals.size();
QByteArray packedNormals = QByteArray(normalsSize * 6 + 1, '0');
// add size of the array
packedNormals[0] = ((uint8_t)normalsSize);
int index = 1;
for (int i = 0; i < normalsSize; i++) {
int numBytes = packFloatVec3ToSignedTwoByteFixed((unsigned char*)packedNormals.data() + index, normals[i], 15);
index += numBytes;
}
return packedNormals;
}
QByteArray EntityItemProperties::getPackedStrokeColors() const {
return packStrokeColors(getStrokeColors());
}
QByteArray EntityItemProperties::packStrokeColors(const QVector<glm::vec3>& strokeColors) const {
int strokeColorsSize = strokeColors.size();
QByteArray packedStrokeColors = QByteArray(strokeColorsSize * 3 + 1, '0');
// add size of the array
packedStrokeColors[0] = ((uint8_t)strokeColorsSize);
for (int i = 0; i < strokeColorsSize; i++) {
// add the color to the QByteArray
packedStrokeColors[i * 3 + 1] = strokeColors[i].r * 255;
packedStrokeColors[i * 3 + 2] = strokeColors[i].g * 255;
packedStrokeColors[i * 3 + 3] = strokeColors[i].b * 255;
}
return packedStrokeColors;
}
// TODO:
// how to handle lastEdited?
// how to handle lastUpdated?
@ -1768,9 +1819,11 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
if (properties.getType() == EntityTypes::PolyLine) {
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QVector<glm::vec3>, setNormals);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QByteArray, setPackedNormals);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_COLORS, QByteArray, setPackedStrokeColors);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IS_UV_MODE_STRETCH, bool, setIsUVModeStretch);
}
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
@ -1801,6 +1854,53 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
return valid;
}
void EntityItemProperties::setPackedNormals(const QByteArray& value) {
setNormals(unpackNormals(value));
}
QVector<glm::vec3> EntityItemProperties::unpackNormals(const QByteArray& normals) {
// the size of the vector is packed first
QVector<glm::vec3> unpackedNormals = QVector<glm::vec3>((int)normals[0]);
if ((int)normals[0] == normals.size() / 6) {
int j = 0;
for (int i = 1; i < normals.size();) {
glm::vec3 aux = glm::vec3();
i += unpackFloatVec3FromSignedTwoByteFixed((unsigned char*)normals.data() + i, aux, 15);
unpackedNormals[j] = aux;
j++;
}
} else {
qCDebug(entities) << "WARNING - Expected received size for normals does not match. Expected: " << (int)normals[0]
<< " Received: " << (normals.size() / 6);
}
return unpackedNormals;
}
void EntityItemProperties::setPackedStrokeColors(const QByteArray& value) {
setStrokeColors(unpackStrokeColors(value));
}
QVector<glm::vec3> EntityItemProperties::unpackStrokeColors(const QByteArray& strokeColors) {
// the size of the vector is packed first
QVector<glm::vec3> unpackedStrokeColors = QVector<glm::vec3>((int)strokeColors[0]);
if ((int)strokeColors[0] == strokeColors.size() / 3) {
int j = 0;
for (int i = 1; i < strokeColors.size();) {
float r = (uint8_t)strokeColors[i++] / 255.0f;
float g = (uint8_t)strokeColors[i++] / 255.0f;
float b = (uint8_t)strokeColors[i++] / 255.0f;
unpackedStrokeColors[j++] = glmVec3(r, g, b);
}
} else {
qCDebug(entities) << "WARNING - Expected received size for stroke colors does not match. Expected: "
<< (int)strokeColors[0] << " Received: " << (strokeColors.size() / 3);
}
return unpackedStrokeColors;
}
// NOTE: This version will only encode the portion of the edit message immediately following the
// header it does not include the send times and sequence number because that is handled by the
@ -1942,7 +2042,9 @@ void EntityItemProperties::markAllChanged() {
_actionDataChanged = true;
_normalsChanged = true;
_strokeColorsChanged = true;
_strokeWidthsChanged = true;
_isUVModeStretchChanged = true;
_xTextureURLChanged = true;
_yTextureURLChanged = true;
@ -2357,6 +2459,14 @@ QList<QString> EntityItemProperties::listChangedProperties() {
out += "shape";
}
if (strokeColorsChanged()) {
out += "strokeColors";
}
if (isUVModeStretchChanged()) {
out += "isUVModeStretch";
}
getAnimation().listChangedProperties(out);
getKeyLight().listChangedProperties(out);
getSkybox().listChangedProperties(out);

View file

@ -191,8 +191,10 @@ public:
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString, "");
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool, TextEntityItem::DEFAULT_FACE_CAMERA);
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray, QByteArray());
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>, QVector<glm::vec3>());
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
DEFINE_PROPERTY(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>, QVector<float>());
DEFINE_PROPERTY(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, bool, true);
DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString, "");
DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString, "");
DEFINE_PROPERTY_REF(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString, "");
@ -322,6 +324,17 @@ public:
bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; }
void setRenderInfoHasTransparent(bool value) { _renderInfoHasTransparent = value; }
void setPackedNormals(const QByteArray& value);
QVector<glm::vec3> unpackNormals(const QByteArray& normals);
void setPackedStrokeColors(const QByteArray& value);
QVector<glm::vec3> unpackStrokeColors(const QByteArray& strokeColors);
QByteArray getPackedNormals() const;
QByteArray packNormals(const QVector<glm::vec3>& normals) const;
QByteArray getPackedStrokeColors() const;
QByteArray packStrokeColors(const QVector<glm::vec3>& strokeColors) const;
protected:
QString getCollisionMaskAsString() const;

View file

@ -24,6 +24,8 @@ const glm::vec3 ENTITY_ITEM_ZERO_VEC3 = glm::vec3(0.0f);
const glm::vec3 ENTITY_ITEM_ONE_VEC3 = glm::vec3(1.0f);
const glm::vec3 ENTITY_ITEM_HALF_VEC3 = glm::vec3(0.5f);
const QVector<glm::vec3> ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC = QVector<glm::vec3>();
const bool ENTITY_ITEM_DEFAULT_LOCKED = false;
const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString("");
const QUuid ENTITY_ITEM_DEFAULT_SIMULATOR_ID = QUuid();

View file

@ -109,7 +109,9 @@ enum EntityPropertyList {
// Used by PolyLine entity
PROP_NORMALS,
PROP_STROKE_COLORS,
PROP_STROKE_WIDTHS,
PROP_IS_UV_MODE_STRETCH,
// used by particles
PROP_SPEED_SPREAD,

View file

@ -22,7 +22,7 @@
#include "PolyLineEntityItem.h"
const float PolyLineEntityItem::DEFAULT_LINE_WIDTH = 0.1f;
const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 70;
const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 60;
EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
@ -31,6 +31,7 @@ EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, cons
return entity;
}
PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) {
_type = EntityTypes::PolyLine;
}
@ -42,12 +43,15 @@ EntityItemProperties PolyLineEntityItem::getProperties(EntityPropertyFlags desir
properties._color = getXColor();
properties._colorChanged = false;
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeColors, getStrokeColors);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(isUVModeStretch, getIsUVModeStretch);
return properties;
}
@ -60,8 +64,10 @@ bool PolyLineEntityItem::setProperties(const EntityItemProperties& properties) {
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeColors, setStrokeColors);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(isUVModeStretch, setIsUVModeStretch);
if (somethingChanged) {
bool wantDebug = false;
@ -108,6 +114,15 @@ bool PolyLineEntityItem::setNormals(const QVector<glm::vec3>& normals) {
return true;
}
bool PolyLineEntityItem::setStrokeColors(const QVector<glm::vec3>& strokeColors) {
withWriteLock([&] {
_strokeColors = strokeColors;
_strokeColorsChanged = true;
});
return true;
}
bool PolyLineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
if (points.size() > MAX_POINTS_PER_LINE) {
return false;
@ -193,8 +208,10 @@ int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da
READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth);
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
READ_ENTITY_PROPERTY(PROP_NORMALS, QVector<glm::vec3>, setNormals);
READ_ENTITY_PROPERTY(PROP_STROKE_COLORS, QVector<glm::vec3>, setStrokeColors);
READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
READ_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, bool, setIsUVModeStretch);
return bytesRead;
}
@ -207,8 +224,10 @@ EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParam
requestedProperties += PROP_LINE_WIDTH;
requestedProperties += PROP_LINE_POINTS;
requestedProperties += PROP_NORMALS;
requestedProperties += PROP_STROKE_COLORS;
requestedProperties += PROP_STROKE_WIDTHS;
requestedProperties += PROP_TEXTURES;
requestedProperties += PROP_IS_UV_MODE_STRETCH;
return requestedProperties;
}
@ -227,8 +246,10 @@ void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, Encode
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth());
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals());
APPEND_ENTITY_PROPERTY(PROP_STROKE_COLORS, getStrokeColors());
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths());
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
APPEND_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, getIsUVModeStretch());
}
void PolyLineEntityItem::debugDump() const {
@ -258,6 +279,14 @@ QVector<glm::vec3> PolyLineEntityItem::getNormals() const {
return result;
}
QVector<glm::vec3> PolyLineEntityItem::getStrokeColors() const {
QVector<glm::vec3> result;
withReadLock([&] {
result = _strokeColors;
});
return result;
}
QVector<float> PolyLineEntityItem::getStrokeWidths() const {
QVector<float> result;
withReadLock([&] {

View file

@ -46,9 +46,11 @@ class PolyLineEntityItem : public EntityItem {
xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; }
void setColor(const rgbColor& value) {
_strokeColorsChanged = true;
memcpy(_color, value, sizeof(_color));
}
void setColor(const xColor& value) {
_strokeColorsChanged = true;
_color[RED_INDEX] = value.red;
_color[GREEN_INDEX] = value.green;
_color[BLUE_INDEX] = value.blue;
@ -64,9 +66,15 @@ class PolyLineEntityItem : public EntityItem {
bool setNormals(const QVector<glm::vec3>& normals);
QVector<glm::vec3> getNormals() const;
bool setStrokeColors(const QVector<glm::vec3>& strokeColors);
QVector<glm::vec3> getStrokeColors() const;
bool setStrokeWidths(const QVector<float>& strokeWidths);
QVector<float> getStrokeWidths() const;
void setIsUVModeStretch(bool isUVModeStretch){ _isUVModeStretch = isUVModeStretch; }
bool getIsUVModeStretch() const{ return _isUVModeStretch; }
QString getTextures() const;
void setTextures(const QString& textures);
@ -76,10 +84,11 @@ class PolyLineEntityItem : public EntityItem {
bool pointsChanged() const { return _pointsChanged; }
bool normalsChanged() const { return _normalsChanged; }
bool strokeColorsChanged() const { return _strokeColorsChanged; }
bool strokeWidthsChanged() const { return _strokeWidthsChanged; }
bool texturesChanged() const { return _texturesChangedFlag; }
void resetTexturesChanged() { _texturesChangedFlag = false; }
void resetPolyLineChanged() { _strokeWidthsChanged = _normalsChanged = _pointsChanged = false; }
void resetPolyLineChanged() { _strokeColorsChanged = _strokeWidthsChanged = _normalsChanged = _pointsChanged = false; }
// never have a ray intersection pick a PolyLineEntityItem.
@ -103,11 +112,14 @@ private:
float _lineWidth { DEFAULT_LINE_WIDTH };
bool _pointsChanged { true };
bool _normalsChanged { true };
bool _strokeColorsChanged { true };
bool _strokeWidthsChanged { true };
QVector<glm::vec3> _points;
QVector<glm::vec3> _normals;
QVector<glm::vec3> _strokeColors;
QVector<float> _strokeWidths;
QString _textures;
bool _isUVModeStretch;
bool _texturesChangedFlag { false };
mutable QReadWriteLock _quadReadWriteLock;
};

View file

@ -29,6 +29,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::EntityAdd:
case PacketType::EntityEdit:
case PacketType::EntityData:
return VERSION_ENTITIES_STROKE_COLOR_PROPERTY;
case PacketType::EntityPhysics:
return VERSION_ENTITIES_HAZE;
case PacketType::EntityQuery:

View file

@ -269,6 +269,9 @@ const PacketVersion VERSION_ENTITIES_HAS_HIGHLIGHT_SCRIPTING_INTERFACE = 72;
const PacketVersion VERSION_ENTITIES_ANIMATION_ALLOW_TRANSLATION_PROPERTIES = 73;
const PacketVersion VERSION_ENTITIES_HAS_CERTIFICATE_PROPERTIES = 74;
const PacketVersion VERSION_ENTITIES_HAZE = 75;
const PacketVersion VERSION_ENTITIES_UV_MODE_PROPERTY = 76;
const PacketVersion VERSION_ENTITIES_STROKE_COLOR_PROPERTY = 77;
enum class EntityQueryPacketVersion: PacketVersion {
JSONFilter = 18,

View file

@ -33,6 +33,7 @@
/// Scriptable interface a Quaternion helper class object. Used exclusively in the JavaScript API
class Quat : public QObject, protected QScriptable {
Q_OBJECT
Q_PROPERTY(glm::quat IDENTITY READ IDENTITY CONSTANT)
public slots:
glm::quat multiply(const glm::quat& q1, const glm::quat& q2);
@ -63,6 +64,10 @@ public slots:
bool equal(const glm::quat& q1, const glm::quat& q2);
glm::quat cancelOutRollAndPitch(const glm::quat& q);
glm::quat cancelOutRoll(const glm::quat& q);
private:
const glm::quat& IDENTITY() const { return Quaternions::IDENTITY; }
};
#endif // hifi_Quat_h

View file

@ -20,6 +20,7 @@
/// Scriptable interface for a UUID helper class object. Used exclusively in the JavaScript API
class ScriptUUID : public QObject, protected QScriptable {
Q_OBJECT
Q_PROPERTY(QString NULL READ NULL_UUID CONSTANT) // String for use in scripts.
public slots:
QUuid fromString(const QString& string);
@ -28,6 +29,10 @@ public slots:
bool isEqual(const QUuid& idA, const QUuid& idB);
bool isNull(const QUuid& id);
void print(const QString& label, const QUuid& id);
private:
const QString NULL_UUID() { return NULL_ID; }
const QString NULL_ID { "{00000000-0000-0000-0000-000000000000}" };
};
#endif // hifi_ScriptUUID_h

View file

@ -41,6 +41,7 @@
#include <gl/OffscreenGLCanvas.h>
#include <gl/GLHelpers.h>
#include <gl/Context.h>
#include <shared/ReadWriteLockable.h>
#include "types/FileTypeProfile.h"
#include "types/HFWebEngineProfile.h"
@ -52,6 +53,53 @@ Q_LOGGING_CATEGORY(trace_render_qml, "trace.render.qml")
Q_LOGGING_CATEGORY(trace_render_qml_gl, "trace.render.qml.gl")
Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus")
class OffscreenQmlWhitelist : public Dependency, private ReadWriteLockable {
SINGLETON_DEPENDENCY
public:
void addWhitelistContextHandler(const std::initializer_list<QUrl>& urls, const QmlContextCallback& callback) {
withWriteLock([&] {
for (const auto& url : urls) {
_callbacks[url].push_back(callback);
}
});
}
QList<QmlContextCallback> getCallbacksForUrl(const QUrl& url) const {
return resultWithReadLock<QList<QmlContextCallback>>([&] {
QList<QmlContextCallback> result;
auto itr = _callbacks.find(url);
if (_callbacks.end() != itr) {
result = *itr;
}
return result;
});
}
private:
QHash<QUrl, QList<QmlContextCallback>> _callbacks;
};
QSharedPointer<OffscreenQmlWhitelist> getQmlWhitelist() {
static std::once_flag once;
std::call_once(once, [&] {
DependencyManager::set<OffscreenQmlWhitelist>();
});
return DependencyManager::get<OffscreenQmlWhitelist>();
}
void OffscreenQmlSurface::addWhitelistContextHandler(const std::initializer_list<QUrl>& urls, const QmlContextCallback& callback) {
getQmlWhitelist()->addWhitelistContextHandler(urls, callback);
}
QmlContextCallback OffscreenQmlSurface::DEFAULT_CONTEXT_CALLBACK = [](QQmlContext*, QObject*) {};
struct TextureSet {
// The number of surfaces with this size
size_t count { 0 };
@ -640,18 +688,26 @@ void OffscreenQmlSurface::setBaseUrl(const QUrl& baseUrl) {
_qmlContext->setBaseUrl(baseUrl);
}
void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, const QmlContextCallback& onQmlLoadedCallback) {
if (QThread::currentThread() != thread()) {
qCWarning(uiLogging) << "Called load on a non-surface thread";
}
// Synchronous loading may take a while; restart the deadlock timer
QMetaObject::invokeMethod(qApp, "updateHeartbeat", Qt::DirectConnection);
// Get any whitelist functionality
QList<QmlContextCallback> callbacks = getQmlWhitelist()->getCallbacksForUrl(qmlSource);
// If we have whitelisted content, we must load a new context
createNewContext |= !callbacks.empty();
callbacks.push_back(onQmlLoadedCallback);
QQmlContext* targetContext = _qmlContext;
if (_rootItem && createNewContext) {
targetContext = new QQmlContext(targetContext);
}
// FIXME eliminate loading of relative file paths for QML
QUrl finalQmlSource = qmlSource;
if ((qmlSource.isRelative() && !qmlSource.isEmpty()) || qmlSource.scheme() == QLatin1String("file")) {
finalQmlSource = _qmlContext->resolvedUrl(qmlSource);
@ -659,29 +715,32 @@ void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, std
auto qmlComponent = new QQmlComponent(_qmlContext->engine(), finalQmlSource, QQmlComponent::PreferSynchronous);
if (qmlComponent->isLoading()) {
connect(qmlComponent, &QQmlComponent::statusChanged, this,
[this, qmlComponent, targetContext, onQmlLoadedCallback](QQmlComponent::Status) {
finishQmlLoad(qmlComponent, targetContext, onQmlLoadedCallback);
connect(qmlComponent, &QQmlComponent::statusChanged, this, [=](QQmlComponent::Status) {
finishQmlLoad(qmlComponent, targetContext, callbacks);
});
return;
}
finishQmlLoad(qmlComponent, targetContext, onQmlLoadedCallback);
finishQmlLoad(qmlComponent, targetContext, callbacks);
}
void OffscreenQmlSurface::loadInNewContext(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
void OffscreenQmlSurface::loadInNewContext(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback) {
load(qmlSource, true, onQmlLoadedCallback);
}
void OffscreenQmlSurface::load(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
void OffscreenQmlSurface::load(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback) {
load(qmlSource, false, onQmlLoadedCallback);
}
void OffscreenQmlSurface::load(const QString& qmlSourceFile, const QmlContextCallback& onQmlLoadedCallback) {
return load(QUrl(qmlSourceFile), onQmlLoadedCallback);
}
void OffscreenQmlSurface::clearCache() {
_qmlContext->engine()->clearComponentCache();
}
void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, const QList<QmlContextCallback>& callbacks) {
disconnect(qmlComponent, &QQmlComponent::statusChanged, this, 0);
if (qmlComponent->isError()) {
for (const auto& error : qmlComponent->errors()) {
@ -716,7 +775,9 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
// Make sure we will call callback for this codepath
// Call this before qmlComponent->completeCreate() otherwise ghost window appears
if (newItem && _rootItem) {
onQmlLoadedCallback(qmlContext, newObject);
for (const auto& callback : callbacks) {
callback(qmlContext, newObject);
}
}
QObject* eventBridge = qmlContext->contextProperty("eventBridge").value<QObject*>();
@ -751,8 +812,11 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
_rootItem = newItem;
_rootItem->setParentItem(_quickWindow->contentItem());
_rootItem->setSize(_quickWindow->renderTargetSize());
// Call this callback after rootitem is set, otherwise VrMenu wont work
onQmlLoadedCallback(qmlContext, newObject);
for (const auto& callback : callbacks) {
callback(qmlContext, newObject);
}
}
void OffscreenQmlSurface::updateQuick() {
@ -1018,7 +1082,24 @@ void OffscreenQmlSurface::synthesizeKeyPress(QString key, QObject* targetOverrid
}
}
static void forEachKeyboard(QQuickItem* item, std::function<void(QQuickItem*)> function) {
static void forEachKeyboard(QQuickItem* parent, std::function<void(QQuickItem*)> function) {
if (!function) {
return;
}
auto keyboards = parent->findChildren<QObject*>("keyboard");
for (auto keyboardObject : keyboards) {
auto keyboard = qobject_cast<QQuickItem*>(keyboardObject);
if (keyboard) {
function(keyboard);
}
}
}
static const int TEXTINPUT_PASSWORD = 2;
static QQuickItem* getTopmostParent(QQuickItem* item) {
QObject* itemObject = item;
while (itemObject) {
if (itemObject->parent()) {
@ -1028,22 +1109,9 @@ static void forEachKeyboard(QQuickItem* item, std::function<void(QQuickItem*)> f
}
}
auto keyboards = itemObject->findChildren<QObject*>("keyboard");
for (auto keyboardObject : keyboards) {
auto keyboard = qobject_cast<QQuickItem*>(keyboardObject);
if (keyboard == nullptr) {
continue;
}
if (function) {
function(keyboard);
}
}
return qobject_cast<QQuickItem*> (itemObject);
}
static const int TEXTINPUT_PASSWORD = 2;
void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool numeric) {
#if Q_OS_ANDROID
return;
@ -1066,10 +1134,14 @@ void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool n
// we need to somehow pass 'isPasswordField' to visible keyboard so it will change its 'mirror text' to asterixes
// the issue in some cases there might be more than one keyboard in object tree and it is hard to understand which one is being used at the moment
// unfortunately attempts to check for visibility failed becuase visibility is not updated yet. So... I don't see other way than just update properties for all the keyboards
forEachKeyboard(item, [&](QQuickItem* keyboard) {
keyboard->setProperty("mirroredText", QVariant::fromValue(QString("")));
keyboard->setProperty("password", isPasswordField);
});
auto topmostParent = getTopmostParent(item);
if (topmostParent) {
forEachKeyboard(topmostParent, [&](QQuickItem* keyboard) {
keyboard->setProperty("mirroredText", QVariant::fromValue(QString("")));
keyboard->setProperty("password", isPasswordField);
});
}
// for future probably makes sense to consider one of the following:
// 1. make keyboard a singleton, which will be dynamically re-parented before showing
@ -1081,6 +1153,11 @@ void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool n
numeric = numeric || QString(item->metaObject()->className()).left(7) == "SpinBox";
if (item->property("keyboardRaised").isValid()) {
forEachKeyboard(item, [&](QQuickItem* keyboard) {
keyboard->setProperty("mirroredText", QVariant::fromValue(QString("")));
keyboard->setProperty("password", isPasswordField);
});
// FIXME - HMD only: Possibly set value of "keyboardEnabled" per isHMDMode() for use in WebView.qml.
if (item->property("punctuationMode").isValid()) {
item->setProperty("punctuationMode", QVariant(numeric));

View file

@ -35,12 +35,18 @@ class QQuickItem;
// one copy in flight, and one copy being used by the receiver
#define GPU_RESOURCE_BUFFER_SIZE 3
using QmlContextCallback = std::function<void(QQmlContext*, QObject*)>;
class OffscreenQmlSurface : public QObject {
Q_OBJECT
Q_PROPERTY(bool focusText READ isFocusText NOTIFY focusTextChanged)
public:
static void setSharedContext(QOpenGLContext* context);
static QmlContextCallback DEFAULT_CONTEXT_CALLBACK;
static void addWhitelistContextHandler(const std::initializer_list<QUrl>& urls, const QmlContextCallback& callback);
static void addWhitelistContextHandler(const QUrl& url, const QmlContextCallback& callback) { addWhitelistContextHandler({ { url } }, callback); };
OffscreenQmlSurface();
virtual ~OffscreenQmlSurface();
@ -50,12 +56,10 @@ public:
void resize(const QSize& size, bool forceResize = false);
QSize size() const;
Q_INVOKABLE void load(const QUrl& qmlSource, bool createNewContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {});
Q_INVOKABLE void loadInNewContext(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {});
Q_INVOKABLE void load(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {});
Q_INVOKABLE void load(const QString& qmlSourceFile, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {}) {
return load(QUrl(qmlSourceFile), onQmlLoadedCallback);
}
Q_INVOKABLE void load(const QUrl& qmlSource, bool createNewContext, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
Q_INVOKABLE void loadInNewContext(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
Q_INVOKABLE void load(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
Q_INVOKABLE void load(const QString& qmlSourceFile, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
void clearCache();
void setMaxFps(uint8_t maxFps) { _maxFps = maxFps; }
// Optional values for event handling
@ -120,7 +124,7 @@ protected:
private:
static QOpenGLContext* getSharedContext();
void finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback);
void finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, const QList<QmlContextCallback>& callbacks);
QPointF mapWindowToUi(const QPointF& sourcePosition, QObject* sourceObject);
void setupFbo();
bool allowNewFrame(uint8_t fps);

View file

@ -32,7 +32,7 @@ var DEFAULT_SCRIPTS_COMBINED = [
"system/tablet-ui/tabletUI.js"
];
var DEFAULT_SCRIPTS_SEPARATE = [
"system/controllers/controllerScripts.js",
"system/controllers/controllerScripts.js"
// "system/chat.js"
];

View file

@ -1,5 +1,3 @@
var AVATAR_SELF_ID = "{00000000-0000-0000-0000-000000000001}";
var debugSphereBaseProperties = {
type: "Sphere",
dimensions: { x: 0.2, y: 0.2, z: 0.2 },

View file

@ -12,7 +12,6 @@
Script.include("libraries/utils.js");
var NULL_UUID = "{00000000-0000-0000-0000-000000000000}";
var DEFAULT_WEARABLE_DATA = {
joints: {}
};
@ -116,7 +115,7 @@ function AttachedEntitiesManager() {
var allowedJoints = getEntityCustomData('wearable', grabbedEntity, DEFAULT_WEARABLE_DATA).joints;
var props = Entities.getEntityProperties(grabbedEntity, ["position", "parentID", "parentJointIndex"]);
if (props.parentID === NULL_UUID || props.parentID === MyAvatar.sessionUUID) {
if (props.parentID === Uuid.NULL || props.parentID === MyAvatar.sessionUUID) {
var bestJointName = "";
var bestJointIndex = -1;
var bestJointDistance = 0;
@ -168,7 +167,7 @@ function AttachedEntitiesManager() {
if (updatePresets) {
this.updateRelativeOffsets(newEntity);
}
} else if (props.parentID != NULL_UUID) {
} else if (props.parentID != Uuid.NULL) {
// drop the entity and set it to have no parent (not on the avatar), unless it's being equipped in a hand.
if (props.parentID === MyAvatar.sessionUUID &&
(props.parentJointIndex == MyAvatar.getJointIndex("RightHand") ||
@ -176,7 +175,7 @@ function AttachedEntitiesManager() {
// this is equipped on a hand -- don't clear the parent.
} else {
var wearProps = Entities.getEntityProperties(grabbedEntity);
wearProps.parentID = NULL_UUID;
wearProps.parentID = Uuid.NULL;
wearProps.parentJointIndex = -1;
delete wearProps.id;
delete wearProps.created;

View file

@ -30,7 +30,6 @@ var OVERLAY_DATA = {
};
var AVATAR_MOVE_FOR_ACTIVE_DISTANCE = 0.8; // meters -- no longer away if avatar moves this far while away
var AVATAR_SELF_ID = "{00000000-0000-0000-0000-000000000001}";
var CAMERA_MATRIX = -7;
var OVERLAY_DATA_HMD = {
@ -44,7 +43,7 @@ var OVERLAY_DATA_HMD = {
scale: 2 * MyAvatar.sensorToWorldScale,
emissive: true,
drawInFront: true,
parentID: AVATAR_SELF_ID,
parentID: MyAvatar.SELF_ID,
parentJointIndex: CAMERA_MATRIX
};

View file

@ -25,10 +25,10 @@
// The bubble model itself
var bubbleOverlay = Overlays.addOverlay("model", {
url: Script.resolvePath("assets/models/Bubble-v14.fbx"), // If you'd like to change the model, modify this line (and the dimensions below)
dimensions: { x: 1.0, y: 0.75, z: 1.0 },
dimensions: { x: MyAvatar.sensorToWorldScale, y: 0.75 * MyAvatar.sensorToWorldScale, z: MyAvatar.sensorToWorldScale },
position: { x: MyAvatar.position.x, y: -MyAvatar.scale * 2 + MyAvatar.position.y + MyAvatar.scale * BUBBLE_HEIGHT_SCALE, z: MyAvatar.position.z },
rotation: Quat.multiply(MyAvatar.orientation, Quat.fromVec3Degrees({x: 0.0, y: 180.0, z: 0.0})),
scale: { x: 2 * MyAvatar.sensorToWorldScale, y: MyAvatar.scale * 0.5 + 0.2 * MyAvatar.sensorToWorldScale, z: 2 * MyAvatar.sensorToWorldScale },
scale: { x: 2 , y: MyAvatar.scale * 0.5 + 0.5, z: 2 },
visible: false,
ignoreRayIntersection: true
});
@ -62,6 +62,11 @@
}
Overlays.editOverlay(bubbleOverlay, {
dimensions: {
x: MyAvatar.sensorToWorldScale,
y: 0.75 * MyAvatar.sensorToWorldScale,
z: MyAvatar.sensorToWorldScale
},
position: {
x: MyAvatar.position.x,
y: -MyAvatar.scale * 2 + MyAvatar.position.y + MyAvatar.scale * BUBBLE_HEIGHT_SCALE,
@ -69,9 +74,9 @@
},
rotation: Quat.multiply(MyAvatar.orientation, Quat.fromVec3Degrees({x: 0.0, y: 180.0, z: 0.0})),
scale: {
x: 2 * MyAvatar.sensorToWorldScale,
y: MyAvatar.scale * 0.5 + 0.2 * MyAvatar.sensorToWorldScale,
z: 2 * MyAvatar.sensorToWorldScale
x: 2 ,
y: MyAvatar.scale * 0.5 + 0.5 ,
z: 2
},
visible: true
});
@ -107,6 +112,11 @@
if (delay < BUBBLE_RAISE_ANIMATION_DURATION_MS) {
Overlays.editOverlay(bubbleOverlay, {
dimensions: {
x: MyAvatar.sensorToWorldScale,
y: 0.75 * MyAvatar.sensorToWorldScale,
z: MyAvatar.sensorToWorldScale
},
// Quickly raise the bubble from the ground up
position: {
x: MyAvatar.position.x,
@ -115,14 +125,19 @@
},
rotation: Quat.multiply(MyAvatar.orientation, Quat.fromVec3Degrees({x: 0.0, y: 180.0, z: 0.0})),
scale: {
x: 2 * MyAvatar.sensorToWorldScale,
y: ((1 - ((BUBBLE_RAISE_ANIMATION_DURATION_MS - delay) / BUBBLE_RAISE_ANIMATION_DURATION_MS)) * MyAvatar.scale * 0.5 + 0.2 * MyAvatar.sensorToWorldScale),
z: 2 * MyAvatar.sensorToWorldScale
x: 2 ,
y: ((1 - ((BUBBLE_RAISE_ANIMATION_DURATION_MS - delay) / BUBBLE_RAISE_ANIMATION_DURATION_MS)) * MyAvatar.scale * 0.5 + 0.5),
z: 2
}
});
} else {
// Keep the bubble in place for a couple seconds
Overlays.editOverlay(bubbleOverlay, {
dimensions: {
x: MyAvatar.sensorToWorldScale,
y: 0.75 * MyAvatar.sensorToWorldScale,
z: MyAvatar.sensorToWorldScale
},
position: {
x: MyAvatar.position.x,
y: MyAvatar.position.y + MyAvatar.scale * BUBBLE_HEIGHT_SCALE,
@ -130,9 +145,9 @@
},
rotation: Quat.multiply(MyAvatar.orientation, Quat.fromVec3Degrees({x: 0.0, y: 180.0, z: 0.0})),
scale: {
x: 2 * MyAvatar.sensorToWorldScale,
y: MyAvatar.scale * 0.5 + 0.2 * MyAvatar.sensorToWorldScale,
z: 2 * MyAvatar.sensorToWorldScale
x: 2,
y: MyAvatar.scale * 0.5 + 0.5 ,
z: 2
}
});
}

View file

@ -27,7 +27,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
var BASIC_TIMER_INTERVAL_MS = 1000 / TARGET_UPDATE_HZ;
var PROFILE = false;
var DEBUG = true;
var DEBUG = false;
if (typeof Test !== "undefined") {
PROFILE = true;

View file

@ -9,8 +9,6 @@
/* globals createControllerDisplay:true deleteControllerDisplay:true */
var PARENT_ID = "{00000000-0000-0000-0000-000000000001}";
function clamp(value, min, max) {
if (value < min) {
return min;
@ -178,7 +176,7 @@ createControllerDisplay = function(config) {
dimensions: Vec3.multiply(sensorScaleFactor, controller.dimensions),
localRotation: controller.rotation,
localPosition: Vec3.multiply(sensorScaleFactor, position),
parentID: PARENT_ID,
parentID: MyAvatar.SELF_ID,
parentJointIndex: controller.jointIndex,
ignoreRayIntersection: true
});
@ -198,7 +196,7 @@ createControllerDisplay = function(config) {
url: part.modelURL,
localPosition: partPosition,
localRotation: innerRotation,
parentID: PARENT_ID,
parentID: MyAvatar.SELF_ID,
parentJointIndex: controller.jointIndex,
ignoreRayIntersection: true
};

View file

@ -6,8 +6,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID,
getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
getControllerJointIndex, enableDispatcherModule, disableDispatcherModule,
Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions,
Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable,
cloneEntity, DISPATCHER_PROPERTIES
@ -333,7 +333,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
var props = controllerData.nearbyEntityPropertiesByID[hotspot.entityID];
var hasParent = true;
if (props.parentID === NULL_UUID) {
if (props.parentID === Uuid.NULL) {
hasParent = false;
}
@ -491,7 +491,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
}
var reparentProps = {
parentID: AVATAR_SELF_ID,
parentID: MyAvatar.SELF_ID,
parentJointIndex: handJointIndex,
localVelocity: {x: 0, y: 0, z: 0},
localAngularVelocity: {x: 0, y: 0, z: 0},
@ -539,7 +539,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
this.endEquipEntity = function () {
Entities.editEntity(this.targetEntityID, {
parentID: NULL_UUID,
parentID: Uuid.NULL,
parentJointIndex: -1
});

View file

@ -8,11 +8,11 @@
/* jslint bitwise: true */
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat,
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID,
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable,
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities,
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable, entityIsGrabbable,
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI
*/
@ -23,6 +23,8 @@ Script.include("/~/system/libraries/controllers.js");
(function() {
var PICK_WITH_HAND_RAY = true;
var SEARCH_SPHERE_SIZE = 0.0132;
var dim = {x: SEARCH_SPHERE_SIZE, y: SEARCH_SPHERE_SIZE, z: SEARCH_SPHERE_SIZE};
var halfPath = {
type: "line3d",
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
@ -33,10 +35,11 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var halfEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
alpha: 0.9,
@ -54,10 +57,11 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var fullEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
alpha: 0.9,
@ -75,7 +79,7 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var renderStates = [
@ -135,10 +139,6 @@ Script.include("/~/system/libraries/controllers.js");
100);
this.updateLaserPointer = function(controllerData) {
var SEARCH_SPHERE_SIZE = 0.011;
var MIN_SPHERE_SIZE = 0.0005;
var radius = Math.max(1.2 * SEARCH_SPHERE_SIZE * this.intersectionDistance, MIN_SPHERE_SIZE) * MyAvatar.sensorToWorldScale;
var dim = {x: radius, y: radius, z: radius};
var mode = "hold";
if (!this.distanceHolding && !this.distanceRotating) {
if (controllerData.triggerClicks[this.hand]) {
@ -150,16 +150,10 @@ Script.include("/~/system/libraries/controllers.js");
var laserPointerID = PICK_WITH_HAND_RAY ? this.laserPointer : this.headLaserPointer;
if (mode === "full") {
var fullEndToEdit = PICK_WITH_HAND_RAY ? this.fullEnd : fullEnd;
fullEndToEdit.dimensions = dim;
LaserPointers.editRenderState(laserPointerID, mode, { path: fullPath, end: fullEndToEdit });
this.contextOverlayTimer = false;
this.destroyContextOverlay();
} else if (mode === "half") {
var halfEndToEdit = PICK_WITH_HAND_RAY ? this.halfEnd : halfEnd;
halfEndToEdit.dimensions = dim;
LaserPointers.editRenderState(laserPointerID, mode, {path: halfPath, end: halfEndToEdit});
}
LaserPointers.enableLaserPointer(laserPointerID);
LaserPointers.setRenderState(laserPointerID, mode);
if (this.distanceHolding || this.distanceRotating) {
@ -238,7 +232,7 @@ Script.include("/~/system/libraries/controllers.js");
tag: "far-grab-" + MyAvatar.sessionUUID,
ttl: ACTION_TTL
});
if (this.actionID === NULL_UUID) {
if (this.actionID === Uuid.NULL) {
this.actionID = null;
}
@ -577,8 +571,6 @@ Script.include("/~/system/libraries/controllers.js");
LaserPointers.removeLaserPointer(this.laserPointer);
};
this.halfEnd = halfEnd;
this.fullEnd = fullEnd;
this.laserPointer = LaserPointers.createLaserPointer({
joint: (this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
@ -586,6 +578,7 @@ Script.include("/~/system/libraries/controllers.js");
posOffset: getGrabPointSphereOffset(this.handToController(), true),
renderStates: renderStates,
faceAvatar: true,
distanceScaleEnd: true,
defaultRenderStates: defaultRenderStates
});
}

View file

@ -9,13 +9,15 @@
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, MyAvatar, getGrabPointSphereOffset,
makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters,
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData
DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData
*/
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
Script.include("/~/system/libraries/controllers.js");
(function() {
var SEARCH_SPHERE_SIZE = 0.0132;
var dim = {x: SEARCH_SPHERE_SIZE, y: SEARCH_SPHERE_SIZE, z: SEARCH_SPHERE_SIZE};
var halfPath = {
type: "line3d",
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
@ -26,10 +28,11 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var halfEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
alpha: 0.9,
@ -47,10 +50,11 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var fullEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
alpha: 0.9,
@ -68,7 +72,7 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var renderStates = [
@ -107,10 +111,6 @@ Script.include("/~/system/libraries/controllers.js");
};
this.updateLaserPointer = function(controllerData) {
var SEARCH_SPHERE_SIZE = 0.011;
var MIN_SPHERE_SIZE = 0.0005;
var radius = Math.max(1.2 * SEARCH_SPHERE_SIZE * this.intersectionDistance, MIN_SPHERE_SIZE);
var dim = {x: radius, y: radius, z: radius};
var mode = "none";
if (controllerData.triggerClicks[this.hand]) {
mode = "full";
@ -118,18 +118,8 @@ Script.include("/~/system/libraries/controllers.js");
mode = "half";
}
var laserPointerID = this.laserPointer;
if (mode === "full") {
var fullEndToEdit = this.fullEnd;
fullEndToEdit.dimensions = dim;
LaserPointers.editRenderState(laserPointerID, mode, {path: fullPath, end: fullEndToEdit});
} else if (mode === "half") {
var halfEndToEdit = this.halfEnd;
halfEndToEdit.dimensions = dim;
LaserPointers.editRenderState(laserPointerID, mode, {path: halfPath, end: halfEndToEdit});
}
LaserPointers.enableLaserPointer(laserPointerID);
LaserPointers.setRenderState(laserPointerID, mode);
LaserPointers.enableLaserPointer(this.laserPointer);
LaserPointers.setRenderState(this.laserPointer, mode);
};
this.laserPointerOff = function() {
@ -192,8 +182,6 @@ Script.include("/~/system/libraries/controllers.js");
return makeRunningValues(true, [this.targetEntityID], []);
};
this.halfEnd = halfEnd;
this.fullEnd = fullEnd;
this.laserPointer = LaserPointers.createLaserPointer({
joint: (this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
@ -201,6 +189,7 @@ Script.include("/~/system/libraries/controllers.js");
posOffset: getGrabPointSphereOffset(this.handToController(), true),
renderStates: renderStates,
faceAvatar: true,
distanceScaleEnd: true,
defaultRenderStates: defaultRenderStates
});

View file

@ -11,17 +11,19 @@
//
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat,
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID,
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities,
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable,
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI
*/
(function() {
Script.include("/~/system/libraries/controllers.js");
var ControllerDispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js");
var END_RADIUS = 0.005;
var dim = { x: END_RADIUS, y: END_RADIUS, z: END_RADIUS };
var halfPath = {
type: "line3d",
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
@ -32,10 +34,11 @@
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawHUDLayer: true,
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var halfEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
alpha: 0.9,
@ -53,10 +56,11 @@
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawHUDLayer: true,
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var fullEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
alpha: 0.9,
@ -74,7 +78,7 @@
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawHUDLayer: true,
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var renderStates = [
@ -126,17 +130,6 @@
};
this.updateLaserPointer = function(controllerData) {
var RADIUS = 0.005;
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
if (this.mode === "full") {
this.fullEnd.dimensions = dim;
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: this.fullEnd});
} else if (this.mode === "half") {
this.halfEnd.dimensions = dim;
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: this.halfEnd});
}
LaserPointers.enableLaserPointer(this.laserPointer);
LaserPointers.setRenderState(this.laserPointer, this.mode);
};
@ -212,8 +205,6 @@
LaserPointers.removeLaserPointer(this.laserPointer);
};
this.halfEnd = halfEnd;
this.fullEnd = fullEnd;
this.laserPointer = LaserPointers.createLaserPointer({
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_HUD,

View file

@ -8,7 +8,7 @@
/* jslint bitwise: true */
/* global Script, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, makeRunningValues,
Messages, makeDispatcherModuleParameters, AVATAR_SELF_ID, HMD, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
Messages, makeDispatcherModuleParameters, HMD, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE,
getEnabledModuleByName, PICK_MAX_DISTANCE, isInEditMode, LaserPointers, RayPick
*/
@ -18,6 +18,8 @@ Script.include("/~/system/libraries/controllers.js");
Script.include("/~/system/libraries/utils.js");
(function () {
var END_RADIUS = 0.005;
var dim = { x: END_RADIUS, y: END_RADIUS, z: END_RADIUS };
var halfPath = {
type: "line3d",
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
@ -28,10 +30,11 @@ Script.include("/~/system/libraries/utils.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var halfEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
alpha: 0.9,
@ -49,10 +52,11 @@ Script.include("/~/system/libraries/utils.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var fullEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
alpha: 0.9,
@ -70,7 +74,7 @@ Script.include("/~/system/libraries/utils.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var renderStates = [
@ -121,17 +125,6 @@ Script.include("/~/system/libraries/utils.js");
};
this.updateLaserPointer = function(controllerData) {
var RADIUS = 0.005;
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
if (this.mode === "full") {
this.fullEnd.dimensions = dim;
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: this.fullEnd});
} else if (this.mode === "half") {
this.halfEnd.dimensions = dim;
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: this.halfEnd});
}
LaserPointers.enableLaserPointer(this.laserPointer);
LaserPointers.setRenderState(this.laserPointer, this.mode);
};
@ -230,10 +223,6 @@ Script.include("/~/system/libraries/utils.js");
LaserPointers.removeLaserPointer(this.laserPointer);
};
this.halfEnd = halfEnd;
this.fullEnd = fullEnd;
this.laserPointer = LaserPointers.createLaserPointer({
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,

View file

@ -6,7 +6,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
getControllerJointIndex, getGrabbableData, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
getControllerJointIndex, getGrabbableData, enableDispatcherModule, disableDispatcherModule,
propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable,
Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues,
TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, findGroupParent, entityIsCloneable, propsAreCloneDynamic, cloneEntity,
@ -101,7 +101,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
kinematicSetVelocity: true,
ignoreIK: this.ignoreIK
});
if (this.actionID === NULL_UUID) {
if (this.actionID === Uuid.NULL) {
this.actionID = null;
return;
}
@ -189,7 +189,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
if (targetProps) {
if ((!propsArePhysical(targetProps) && !propsAreCloneDynamic(targetProps)) ||
targetProps.parentID != NULL_UUID) {
targetProps.parentID !== Uuid.NULL) {
return makeRunningValues(false, [], []); // let nearParentGrabEntity handle it
} else {
this.targetEntityID = targetProps.id;

View file

@ -6,7 +6,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID,
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, getControllerJointIndex,
enableDispatcherModule, disableDispatcherModule, propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS,
findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH,
@ -50,7 +50,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
return false;
}
if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== AVATAR_SELF_ID) {
if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== MyAvatar.SELF_ID) {
return false;
}
@ -90,7 +90,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
Entities.callEntityMethod(targetProps.id, "startNearGrab", args);
var reparentProps = {
parentID: AVATAR_SELF_ID,
parentID: MyAvatar.SELF_ID,
parentJointIndex: handJointIndex,
localVelocity: {x: 0, y: 0, z: 0},
localAngularVelocity: {x: 0, y: 0, z: 0}
@ -120,7 +120,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
this.hapticTargetID = null;
var props = controllerData.nearbyEntityPropertiesByID[this.targetEntityID];
if (this.thisHandIsParent(props)) {
if (this.previousParentID[this.targetEntityID] === NULL_UUID || this.previousParentID === undefined) {
if (this.previousParentID[this.targetEntityID] === Uuid.NULL || this.previousParentID === undefined) {
Entities.editEntity(this.targetEntityID, {
parentID: this.previousParentID[this.targetEntityID],
parentJointIndex: this.previousParentJointIndex[this.targetEntityID]
@ -152,7 +152,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
var now = Date.now();
if (now - this.lastUnequipCheckTime > MSECS_PER_SEC * TEAR_AWAY_CHECK_TIME) {
this.lastUnequipCheckTime = now;
if (props.parentID == AVATAR_SELF_ID) {
if (props.parentID === MyAvatar.SELF_ID) {
var sensorScaleFactor = MyAvatar.sensorToWorldScale;
var handPosition = controllerData.controllerLocations[this.hand].position;
var dist = distanceBetweenPointAndEntityBoundingBox(handPosition, props);
@ -198,7 +198,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
var UNHOOK_LOOP_DETECT_MS = 200;
if (_this.previouslyUnhooked[childID]) {
if (now - _this.previouslyUnhooked[childID] < UNHOOK_LOOP_DETECT_MS) {
previousParentID = NULL_UUID;
previousParentID = Uuid.NULL;
previousParentJointIndex = -1;
}
}
@ -209,7 +209,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
parentJointIndex: previousParentJointIndex
});
} else {
Entities.editEntity(childID, { parentID: NULL_UUID });
Entities.editEntity(childID, { parentID: Uuid.NULL });
}
});
}
@ -258,7 +258,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
if (targetProps) {
if ((propsArePhysical(targetProps) || propsAreCloneDynamic(targetProps)) &&
targetProps.parentID == NULL_UUID) {
targetProps.parentID === Uuid.NULL) {
return makeRunningValues(false, [], []); // let nearActionGrabEntity handle it
} else {
this.targetEntityID = targetProps.id;
@ -273,7 +273,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
this.run = function (controllerData, deltaTime) {
if (this.grabbing) {
if (controllerData.triggerClicks[this.hand] < TRIGGER_OFF_VALUE &&
controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) {
controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) {
this.endNearParentingGrabEntity(controllerData);
return makeRunningValues(false, [], []);
}

View file

@ -6,7 +6,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID,
/* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, getControllerJointIndex,
enableDispatcherModule, disableDispatcherModule, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
makeDispatcherModuleParameters, Overlays, makeRunningValues, Vec3, resizeTablet, getTabletWidthFromSettings,
NEAR_GRAB_RADIUS
@ -48,7 +48,7 @@ Script.include("/~/system/libraries/utils.js");
};
this.thisHandIsParent = function(props) {
if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== AVATAR_SELF_ID) {
if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== MyAvatar.SELF_ID) {
return false;
}
@ -94,7 +94,7 @@ Script.include("/~/system/libraries/utils.js");
var grabbedProperties = this.getGrabbedProperties();
var reparentProps = {
parentID: AVATAR_SELF_ID,
parentID: MyAvatar.SELF_ID,
parentJointIndex: handJointIndex,
velocity: {x: 0, y: 0, z: 0},
angularVelocity: {x: 0, y: 0, z: 0}
@ -130,9 +130,9 @@ Script.include("/~/system/libraries/utils.js");
this.endNearParentingGrabOverlay = function () {
var previousParentID = this.previousParentID[this.grabbedThingID];
if ((previousParentID === NULL_UUID || previousParentID === null) && !this.robbed) {
if ((previousParentID === Uuid.NULL || previousParentID === null) && !this.robbed) {
Overlays.editOverlay(this.grabbedThingID, {
parentID: NULL_UUID,
parentID: Uuid.NULL,
parentJointIndex: -1
});
} else if (!this.robbed){

View file

@ -5,8 +5,8 @@
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
makeRunningValues, Messages, Quat, Vec3, makeDispatcherModuleParameters, Overlays, ZERO_VEC, AVATAR_SELF_ID, HMD,
/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule,
makeRunningValues, Messages, Quat, Vec3, makeDispatcherModuleParameters, Overlays, ZERO_VEC, HMD,
INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE,
TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, LaserPointers, RayPick, ContextOverlay
@ -17,6 +17,8 @@ Script.include("/~/system/libraries/controllers.js");
(function() {
var TouchEventUtils = Script.require("/~/system/libraries/touchEventUtils.js");
var END_RADIUS = 0.005;
var dim = { x: END_RADIUS, y: END_RADIUS, z: END_RADIUS };
var halfPath = {
type: "line3d",
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
@ -27,10 +29,11 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var halfEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
alpha: 0.9,
@ -48,10 +51,11 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var fullEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
alpha: 0.9,
@ -69,7 +73,7 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var renderStates = [
@ -171,17 +175,6 @@ Script.include("/~/system/libraries/controllers.js");
};
this.updateLaserPointer = function(controllerData) {
var RADIUS = 0.005;
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
if (this.mode === "full") {
this.fullEnd.dimensions = dim;
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: this.fullEnd});
} else if (this.mode === "half") {
this.halfEnd.dimensions = dim;
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: this.halfEnd});
}
LaserPointers.enableLaserPointer(this.laserPointer);
LaserPointers.setRenderState(this.laserPointer, this.mode);
};
@ -235,7 +228,7 @@ Script.include("/~/system/libraries/controllers.js");
var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds
if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY ||
distance2D(this.laserTarget.position2D,
this.pressEnterLaserTarget.position2D) > this.deadspotRadius) {
this.pressEnterLaserTarget.position2D) > this.deadspotRadius) {
TouchEventUtils.sendTouchMoveEventToTouchTarget(this.hand, this.laserTarget);
this.deadspotExpired = true;
}
@ -366,8 +359,6 @@ Script.include("/~/system/libraries/controllers.js");
LaserPointers.removeLaserPointer(this.laserPointer);
};
this.halfEnd = halfEnd;
this.fullEnd = fullEnd;
this.laserPointer = LaserPointers.createLaserPointer({
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
filter: RayPick.PICK_OVERLAYS,

View file

@ -6,9 +6,9 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues,
enableDispatcherModule, disableDispatcherModule, makeRunningValues,
Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC,
AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset,
HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset,
getEnabledModuleByName
*/
@ -172,7 +172,7 @@ Script.include("/~/system/libraries/controllers.js");
visible: true,
ignoreRayIntersection: true,
drawInFront: false,
parentID: AVATAR_SELF_ID,
parentID: MyAvatar.SELF_ID,
parentJointIndex: MyAvatar.getJointIndex(this.hand === RIGHT_HAND ?
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND")
@ -288,7 +288,7 @@ Script.include("/~/system/libraries/controllers.js");
}
// add the tabletScreen, if it is valid
if (HMD.tabletScreenID && HMD.tabletScreenID !== NULL_UUID &&
if (HMD.tabletScreenID && HMD.tabletScreenID !== Uuid.NULL &&
Overlays.getProperty(HMD.tabletScreenID, "visible")) {
stylusTarget = TouchEventUtils.calculateTouchTargetFromOverlay(this.stylusTip, HMD.tabletScreenID);
if (stylusTarget) {
@ -297,7 +297,7 @@ Script.include("/~/system/libraries/controllers.js");
}
// add the tablet home button.
if (HMD.homeButtonID && HMD.homeButtonID !== NULL_UUID &&
if (HMD.homeButtonID && HMD.homeButtonID !== Uuid.NULL &&
Overlays.getProperty(HMD.homeButtonID, "visible")) {
stylusTarget = TouchEventUtils.calculateTouchTargetFromOverlay(this.stylusTip, HMD.homeButtonID);
if (stylusTarget) {

View file

@ -10,7 +10,7 @@
/* jslint bitwise: true */
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID,
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, getControllerJointIndex,
enableDispatcherModule, disableDispatcherModule, Messages, makeDispatcherModuleParameters, makeRunningValues, Vec3,
LaserPointers, RayPick, HMD, Uuid, AvatarList
*/
@ -107,6 +107,7 @@ Script.include("/~/system/libraries/controllers.js");
ignoreRayIntersection: true
};
var teleportRenderStates = [{name: "cancel", path: cancelPath, end: cancelEnd},
{name: "teleport", path: teleportPath, end: teleportEnd},
{name: "seat", path: seatPath, end: seatEnd}];
@ -117,6 +118,7 @@ Script.include("/~/system/libraries/controllers.js");
var coolInTimeout = null;
var ignoredEntities = [];
var TELEPORTER_STATES = {
IDLE: 'idle',
COOL_IN: 'cool_in',

View file

@ -8,15 +8,17 @@
/* jslint bitwise: true */
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Vec3, Quat, getGrabPointSphereOffset,
makeRunningValues, Entities, NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters,
makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters,
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, ZERO_VEC, Overlays
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, ZERO_VEC, Overlays
*/
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
Script.include("/~/system/libraries/controllers.js");
(function() {
var END_RADIUS = 0.005;
var dim = { x: END_RADIUS, y: END_RADIUS, z: END_RADIUS };
var halfPath = {
type: "line3d",
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
@ -27,10 +29,11 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var halfEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
alpha: 0.9,
@ -48,10 +51,11 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var fullEnd = {
type: "sphere",
dimensions: dim,
solid: true,
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
alpha: 0.9,
@ -69,7 +73,7 @@ Script.include("/~/system/libraries/controllers.js");
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
parentID: AVATAR_SELF_ID
parentID: MyAvatar.SELF_ID
};
var renderStates = [
@ -90,15 +94,15 @@ Script.include("/~/system/libraries/controllers.js");
var HAPTIC_STYLUS_DURATION = 20.0;
function laserTargetHasKeyboardFocus(laserTarget) {
if (laserTarget && laserTarget !== NULL_UUID) {
if (laserTarget && laserTarget !== Uuid.NULL) {
return Entities.keyboardFocusOverlay === laserTarget;
}
}
function setKeyboardFocusOnLaserTarget(laserTarget) {
if (laserTarget && laserTarget !== NULL_UUID) {
if (laserTarget && laserTarget !== Uuid.NULL) {
Entities.wantsHandControllerPointerEvents(laserTarget);
Overlays.keyboardFocusOverlay = NULL_UUID;
Overlays.keyboardFocusOverlay = Uuid.NULL;
Entities.keyboardFocusEntity = laserTarget;
}
}
@ -117,7 +121,7 @@ Script.include("/~/system/libraries/controllers.js");
button: "None"
};
if (laserTarget.entityID && laserTarget.entityID !== NULL_UUID) {
if (laserTarget.entityID && laserTarget.entityID !== Uuid.NULL) {
Entities.sendHoverEnterEntity(laserTarget.entityID, pointerEvent);
}
}
@ -137,7 +141,7 @@ Script.include("/~/system/libraries/controllers.js");
button: "None"
};
if (laserTarget.entityID && laserTarget.entityID !== NULL_UUID) {
if (laserTarget.entityID && laserTarget.entityID !== Uuid.NULL) {
Entities.sendMouseMoveOnEntity(laserTarget.entityID, pointerEvent);
Entities.sendHoverOverEntity(laserTarget.entityID, pointerEvent);
}
@ -156,7 +160,7 @@ Script.include("/~/system/libraries/controllers.js");
isPrimaryHeld: true
};
if (laserTarget.entityID && laserTarget.entityID !== NULL_UUID) {
if (laserTarget.entityID && laserTarget.entityID !== Uuid.NULL) {
Entities.sendMousePressOnEntity(laserTarget.entityID, pointerEvent);
Entities.sendClickDownOnEntity(laserTarget.entityID, pointerEvent);
}
@ -173,7 +177,7 @@ Script.include("/~/system/libraries/controllers.js");
button: "Primary"
};
if (laserTarget.entityID && laserTarget.entityID !== NULL_UUID) {
if (laserTarget.entityID && laserTarget.entityID !== Uuid.NULL) {
Entities.sendMouseReleaseOnEntity(laserTarget.entityID, pointerEvent);
Entities.sendClickReleaseOnEntity(laserTarget.entityID, pointerEvent);
Entities.sendHoverLeaveEntity(laserTarget.entityID, pointerEvent);
@ -192,7 +196,7 @@ Script.include("/~/system/libraries/controllers.js");
isPrimaryHeld: true
};
if (laserTarget.entityID && laserTarget.entityID !== NULL_UUID) {
if (laserTarget.entityID && laserTarget.entityID !== Uuid.NULL) {
Entities.sendMouseMoveOnEntity(laserTarget.entityID, pointerEvent);
Entities.sendHoldingClickOnEntity(laserTarget.entityID, pointerEvent);
}
@ -366,17 +370,6 @@ Script.include("/~/system/libraries/controllers.js");
};
this.updateLaserPointer = function(controllerData) {
var RADIUS = 0.005;
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
if (this.mode === "full") {
fullEnd.dimensions = dim;
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: fullEnd});
} else if (this.mode === "half") {
halfEnd.dimensions = dim;
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: halfEnd});
}
LaserPointers.enableLaserPointer(this.laserPointer);
LaserPointers.setRenderState(this.laserPointer, this.mode);
};

View file

@ -1360,7 +1360,7 @@ function unparentSelectedEntities() {
}
selectedEntities.forEach(function (id, index) {
var parentId = Entities.getEntityProperties(id, ["parentID"]).parentID;
if (parentId !== null && parentId.length > 0 && parentId !== "{00000000-0000-0000-0000-000000000000}") {
if (parentId !== null && parentId.length > 0 && parentId !== Uuid.NULL) {
parentCheck = true;
}
Entities.editEntity(id, {parentID: null});
@ -1476,10 +1476,19 @@ function onFileSaveChanged(filename) {
function onFileOpenChanged(filename) {
// disconnect the event, otherwise the requests will stack up
Window.openFileChanged.disconnect(onFileOpenChanged);
try {
// Not all calls to onFileOpenChanged() connect an event.
Window.openFileChanged.disconnect(onFileOpenChanged);
} catch (e) {
// Ignore.
}
var importURL = null;
if (filename !== "") {
importURL = "file:///" + filename;
importURL = filename;
if (!/^(http|https):\/\//.test(filename)) {
importURL = "file:///" + importURL;
}
}
if (importURL) {
if (!isActive && (Entities.canRez() && Entities.canRezTmp())) {

View file

@ -68,6 +68,7 @@ For usage and examples: colpick.com/plugin
cal.data('colpick').color = col = hexToHsb(fixHex(this.value));
fillRGBFields(col, cal.get(0));
fillHSBFields(col, cal.get(0));
fillHexFields(col, cal.get(0));
} else if (this.parentNode.className.indexOf('_hsb') > 0) {
cal.data('colpick').color = col = fixHSB({
h: parseInt(cal.data('colpick').fields.eq(4).val(), 10),
@ -76,6 +77,7 @@ For usage and examples: colpick.com/plugin
});
fillRGBFields(col, cal.get(0));
fillHexFields(col, cal.get(0));
fillHSBFields(col, cal.get(0));
} else {
cal.data('colpick').color = col = rgbToHsb(fixRGB({
r: parseInt(cal.data('colpick').fields.eq(1).val(), 10),
@ -84,6 +86,7 @@ For usage and examples: colpick.com/plugin
}));
fillHexFields(col, cal.get(0));
fillHSBFields(col, cal.get(0));
fillRGBFields(col, cal.get(0));
}
setSelector(col, cal.get(0));
setHue(col, cal.get(0));

View file

@ -140,6 +140,10 @@
if (!$('body').hasClass("login-injected") && !userIsLoggedIn) {
$('body').addClass("login-injected");
var resultsElement = document.getElementById('results');
if (!resultsElement) { // If we're on the main page, this will evaluate to `true`
resultsElement = document.getElementById('item-show');
resultsElement.style = 'margin-top:0;';
}
var logInElement = document.createElement('div');
logInElement.classList.add("row");
logInElement.id = "logInDiv";
@ -193,6 +197,11 @@
var navbarBrandElement = document.getElementsByClassName('navbar-brand')[0];
var purchasesElement = document.createElement('a');
var dropDownElement = document.getElementById('user-dropdown');
$('#user-dropdown').find('.username')[0].style = "max-width:80px;white-space:nowrap;overflow:hidden;" +
"text-overflow:ellipsis;display:inline-block;position:relative;top:4px;";
$('#user-dropdown').find('.caret')[0].style = "position:relative;top:-3px;";
purchasesElement.id = "purchasesButton";
purchasesElement.setAttribute('href', "#");
purchasesElement.innerHTML = "My Purchases";

View file

@ -25,7 +25,6 @@ var ROT_LANDSCAPE = {x: 1.0, y: 1.0, z: 0, w: 0};
var ROT_LANDSCAPE_WINDOW = {x: 0.0, y: 0.0, z: 0.0, w: 0};
var TABLET_TEXTURE_RESOLUTION = { x: 480, y: 706 };
var INCHES_TO_METERS = 1 / 39.3701;
var AVATAR_SELF_ID = "{00000000-0000-0000-0000-000000000001}";
var NO_HANDS = -1;
var DELAY_FOR_30HZ = 33; // milliseconds
@ -100,7 +99,7 @@ WebTablet = function (url, width, dpi, hand, clientOnly, location, visible) {
"grabbableKey": {"grabbable": true}
}),
dimensions: { x: tabletWidth, y: tabletHeight, z: tabletDepth },
parentID: AVATAR_SELF_ID,
parentID: MyAvatar.SELF_ID,
visible: visible
};
@ -471,7 +470,7 @@ WebTablet.prototype.register = function() {
WebTablet.prototype.cleanUpOldTabletsOnJoint = function(jointIndex) {
var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, jointIndex);
children = children.concat(Entities.getChildrenIDsOfJoint(AVATAR_SELF_ID, jointIndex));
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.SELF_ID, jointIndex));
children.forEach(function(childID) {
var props = Entities.getEntityProperties(childID, ["name"]);
if (props.name === "WebTablet Tablet") {

View file

@ -7,7 +7,7 @@
/* global module, Camera, HMD, MyAvatar, controllerDispatcherPlugins:true, Quat, Vec3, Overlays, Xform,
MSECS_PER_SEC:true , LEFT_HAND:true, RIGHT_HAND:true, NULL_UUID:true, AVATAR_SELF_ID:true, FORBIDDEN_GRAB_TYPES:true,
MSECS_PER_SEC:true , LEFT_HAND:true, RIGHT_HAND:true, FORBIDDEN_GRAB_TYPES:true,
HAPTIC_PULSE_STRENGTH:true, HAPTIC_PULSE_DURATION:true, ZERO_VEC:true, ONE_VEC:true,
DEFAULT_REGISTRATION_POINT:true, INCHES_TO_METERS:true,
TRIGGER_OFF_VALUE:true,
@ -60,9 +60,6 @@ ONE_VEC = { x: 1, y: 1, z: 1 };
LEFT_HAND = 0;
RIGHT_HAND = 1;
NULL_UUID = "{00000000-0000-0000-0000-000000000000}";
AVATAR_SELF_ID = "{00000000-0000-0000-0000-000000000001}";
FORBIDDEN_GRAB_TYPES = ["Unknown", "Light", "PolyLine", "Zone"];
HAPTIC_PULSE_STRENGTH = 1.0;
@ -284,7 +281,7 @@ ensureDynamic = function (entityID) {
// if we distance hold something and keep it very still before releasing it, it ends up
// non-dynamic in bullet. If it's too still, give it a little bounce so it will fall.
var props = Entities.getEntityProperties(entityID, ["velocity", "dynamic", "parentID"]);
if (props.dynamic && props.parentID === NULL_UUID) {
if (props.dynamic && props.parentID === Uuid.NULL) {
var velocity = props.velocity;
if (Vec3.length(velocity) < 0.05) { // see EntityMotionState.cpp DYNAMIC_LINEAR_VELOCITY_THRESHOLD
velocity = { x: 0.0, y: 0.2, z: 0.0 };
@ -295,7 +292,7 @@ ensureDynamic = function (entityID) {
findGroupParent = function (controllerData, targetProps) {
while (targetProps.parentID &&
targetProps.parentID !== NULL_UUID &&
targetProps.parentID !== Uuid.NULL &&
Entities.getNestableType(targetProps.parentID) == "entity") {
var parentProps = Entities.getEntityProperties(targetProps.parentID, DISPATCHER_PROPERTIES);
if (!parentProps) {
@ -314,19 +311,19 @@ findHandChildEntities = function(hand) {
// find children of avatar's hand joint
var handJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ? "RightHand" : "LeftHand");
var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, handJointIndex);
children = children.concat(Entities.getChildrenIDsOfJoint(AVATAR_SELF_ID, handJointIndex));
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.SELF_ID, handJointIndex));
// find children of faux controller joint
var controllerJointIndex = getControllerJointIndex(hand);
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, controllerJointIndex));
children = children.concat(Entities.getChildrenIDsOfJoint(AVATAR_SELF_ID, controllerJointIndex));
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.SELF_ID, controllerJointIndex));
// find children of faux camera-relative controller joint
var controllerCRJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ?
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, controllerCRJointIndex));
children = children.concat(Entities.getChildrenIDsOfJoint(AVATAR_SELF_ID, controllerCRJointIndex));
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.SELF_ID, controllerCRJointIndex));
return children.filter(function (childID) {
var childType = Entities.getNestableType(childID);

View file

@ -118,20 +118,12 @@ CameraManager = function() {
that.targetYaw = 0;
that.targetPitch = 0;
that.focalPoint = {
x: 0,
y: 0,
z: 0
};
that.targetFocalPoint = {
x: 0,
y: 0,
z: 0
};
that.focalPoint = Vec3.ZERO;
that.targetFocalPoint = Vec3.ZERO;
easing = false;
easingTime = 0;
startOrientation = Quat.fromPitchYawRollDegrees(0, 0, 0);
startOrientation = Quat.IDENTITY;
that.previousCameraMode = null;

View file

@ -71,44 +71,16 @@ SelectionManager = (function() {
that.selections = [];
var listeners = [];
that.localRotation = Quat.fromPitchYawRollDegrees(0, 0, 0);
that.localPosition = {
x: 0,
y: 0,
z: 0
};
that.localDimensions = {
x: 0,
y: 0,
z: 0
};
that.localRegistrationPoint = {
x: 0.5,
y: 0.5,
z: 0.5
};
that.localRotation = Quat.IDENTITY;
that.localPosition = Vec3.ZERO;
that.localDimensions = Vec3.ZERO;
that.localRegistrationPoint = Vec3.HALF;
that.worldRotation = Quat.fromPitchYawRollDegrees(0, 0, 0);
that.worldPosition = {
x: 0,
y: 0,
z: 0
};
that.worldDimensions = {
x: 0,
y: 0,
z: 0
};
that.worldRegistrationPoint = {
x: 0.5,
y: 0.5,
z: 0.5
};
that.centerPosition = {
x: 0,
y: 0,
z: 0
};
that.worldRotation = Quat.IDENTITY;
that.worldPosition = Vec3.ZERO;
that.worldDimensions = Vec3.ZERO;
that.worldRegistrationPoint = Vec3.HALF;
that.centerPosition = Vec3.ZERO;
that.saveProperties = function() {
that.savedProperties = {};
@ -350,11 +322,7 @@ SelectionDisplay = (function() {
};
var grabberLineWidth = 0.5;
var grabberSolid = true;
var grabberMoveUpPosition = {
x: 0,
y: 0,
z: 0
};
var grabberMoveUpPosition = Vec3.ZERO;
var lightOverlayColor = {
red: 255,
@ -363,11 +331,7 @@ SelectionDisplay = (function() {
};
var grabberPropertiesCorner = {
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
size: grabberSizeCorner,
color: grabberColorCorner,
alpha: 1,
@ -380,11 +344,7 @@ SelectionDisplay = (function() {
};
var grabberPropertiesEdge = {
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
size: grabberSizeEdge,
color: grabberColorEdge,
alpha: 1,
@ -397,11 +357,7 @@ SelectionDisplay = (function() {
};
var grabberPropertiesFace = {
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
size: grabberSizeFace,
color: grabberColorFace,
alpha: 1,
@ -414,11 +370,7 @@ SelectionDisplay = (function() {
};
var grabberPropertiesCloner = {
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
size: grabberSizeCorner,
color: grabberColorCloner,
alpha: 1,
@ -436,11 +388,7 @@ SelectionDisplay = (function() {
};
var highlightBox = Overlays.addOverlay("cube", {
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
size: 1,
color: {
red: 90,
@ -457,11 +405,7 @@ SelectionDisplay = (function() {
});
var selectionBox = Overlays.addOverlay("cube", {
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
size: 1,
color: {
red: 255,
@ -478,11 +422,7 @@ SelectionDisplay = (function() {
var selectionBoxes = [];
var rotationDegreesDisplay = Overlays.addOverlay("text3d", {
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
text: "",
color: {
red: 0,
@ -513,11 +453,7 @@ SelectionDisplay = (function() {
var grabberMoveUp = Overlays.addOverlay("image3d", {
url: HIFI_PUBLIC_BUCKET + "images/up-arrow.svg",
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
color: handleColor,
alpha: handleAlpha,
visible: false,
@ -720,16 +656,8 @@ SelectionDisplay = (function() {
var xRailOverlay = Overlays.addOverlay("line3d", {
visible: false,
lineWidth: 1.0,
start: {
x: 0,
y: 0,
z: 0
},
end: {
x: 0,
y: 0,
z: 0
},
start: Vec3.ZERO,
end: Vec3.ZERO,
color: {
red: 255,
green: 0,
@ -740,16 +668,8 @@ SelectionDisplay = (function() {
var yRailOverlay = Overlays.addOverlay("line3d", {
visible: false,
lineWidth: 1.0,
start: {
x: 0,
y: 0,
z: 0
},
end: {
x: 0,
y: 0,
z: 0
},
start: Vec3.ZERO,
end: Vec3.ZERO,
color: {
red: 0,
green: 255,
@ -760,16 +680,8 @@ SelectionDisplay = (function() {
var zRailOverlay = Overlays.addOverlay("line3d", {
visible: false,
lineWidth: 1.0,
start: {
x: 0,
y: 0,
z: 0
},
end: {
x: 0,
y: 0,
z: 0
},
start: Vec3.ZERO,
end: Vec3.ZERO,
color: {
red: 0,
green: 0,
@ -781,16 +693,8 @@ SelectionDisplay = (function() {
var rotateZeroOverlay = Overlays.addOverlay("line3d", {
visible: false,
lineWidth: 2.0,
start: {
x: 0,
y: 0,
z: 0
},
end: {
x: 0,
y: 0,
z: 0
},
start: Vec3.ZERO,
end: Vec3.ZERO,
color: {
red: 255,
green: 0,
@ -802,16 +706,8 @@ SelectionDisplay = (function() {
var rotateCurrentOverlay = Overlays.addOverlay("line3d", {
visible: false,
lineWidth: 2.0,
start: {
x: 0,
y: 0,
z: 0
},
end: {
x: 0,
y: 0,
z: 0
},
start: Vec3.ZERO,
end: Vec3.ZERO,
color: {
red: 0,
green: 0,
@ -822,11 +718,7 @@ SelectionDisplay = (function() {
var rotateOverlayInner = Overlays.addOverlay("circle3d", {
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
size: 1,
color: {
red: 51,
@ -856,11 +748,7 @@ SelectionDisplay = (function() {
});
var rotateOverlayOuter = Overlays.addOverlay("circle3d", {
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
size: 1,
color: {
red: 51,
@ -891,11 +779,7 @@ SelectionDisplay = (function() {
});
var rotateOverlayCurrent = Overlays.addOverlay("circle3d", {
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
size: 1,
color: {
red: 224,
@ -922,11 +806,7 @@ SelectionDisplay = (function() {
var yawHandle = Overlays.addOverlay("image3d", {
url: ROTATE_ARROW_WEST_NORTH_URL,
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
color: handleColor,
alpha: handleAlpha,
visible: false,
@ -939,11 +819,7 @@ SelectionDisplay = (function() {
var pitchHandle = Overlays.addOverlay("image3d", {
url: ROTATE_ARROW_WEST_NORTH_URL,
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
color: handleColor,
alpha: handleAlpha,
visible: false,
@ -956,11 +832,7 @@ SelectionDisplay = (function() {
var rollHandle = Overlays.addOverlay("image3d", {
url: ROTATE_ARROW_WEST_NORTH_URL,
position: {
x: 0,
y: 0,
z: 0
},
position: Vec3.ZERO,
color: handleColor,
alpha: handleAlpha,
visible: false,
@ -1636,7 +1508,7 @@ SelectionDisplay = (function() {
position = SelectionManager.localPosition;
registrationPoint = SelectionManager.localRegistrationPoint;
} else {
rotation = Quat.fromPitchYawRollDegrees(0, 0, 0);
rotation = Quat.IDENTITY;
dimensions = SelectionManager.worldDimensions;
position = SelectionManager.worldPosition;
registrationPoint = SelectionManager.worldRegistrationPoint;
@ -2692,7 +2564,7 @@ SelectionDisplay = (function() {
var onBegin = function(event, pickRay, pickResult) {
var properties = Entities.getEntityProperties(SelectionManager.selections[0]);
initialProperties = properties;
rotation = (spaceMode === SPACE_LOCAL) ? properties.rotation : Quat.fromPitchYawRollDegrees(0, 0, 0);
rotation = (spaceMode === SPACE_LOCAL) ? properties.rotation : Quat.IDENTITY;
if (spaceMode === SPACE_LOCAL) {
rotation = SelectionManager.localRotation;

View file

@ -18,7 +18,7 @@ OverlayGroup = function(opts) {
var overlays = {};
var rootPosition = opts.position || { x: 0, y: 0, z: 0 };
var rootRotation = opts.rotation || Quat.fromPitchYawRollRadians(0, 0, 0);
var rootRotation = opts.rotation || Quat.IDENTITY;
var visible = opts.visible == true;
function updateOverlays() {
@ -36,7 +36,7 @@ OverlayGroup = function(opts) {
that.createOverlay = function(type, properties) {
properties.position = properties.position || { x: 0, y: 0, z: 0 };
properties.rotation = properties.rotation || Quat.fromPitchYawRollRadians(0, 0, 0);
properties.rotation = properties.rotation || Quat.IDENTITY;
var overlay = Overlays.addOverlay(type, properties);

View file

@ -6,28 +6,28 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
controllerDispatcher.NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues,
enableDispatcherModule, disableDispatcherModule, makeRunningValues,
Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, controllerDispatcher.ZERO_VEC,
AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset
HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset
*/
var controllerDispatcher = Script.require("/~/system/libraries/controllerDispatcherUtils.js");
function touchTargetHasKeyboardFocus(touchTarget) {
if (touchTarget.entityID && touchTarget.entityID !== controllerDispatcher.NULL_UUID) {
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NULL) {
return Entities.keyboardFocusEntity === touchTarget.entityID;
} else if (touchTarget.overlayID && touchTarget.overlayID !== controllerDispatcher.NULL_UUID) {
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NULL) {
return Overlays.keyboardFocusOverlay === touchTarget.overlayID;
}
}
function setKeyboardFocusOnTouchTarget(touchTarget) {
if (touchTarget.entityID && touchTarget.entityID !== controllerDispatcher.NULL_UUID &&
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NULL &&
Entities.wantsHandControllerPointerEvents(touchTarget.entityID)) {
Overlays.keyboardFocusOverlay = controllerDispatcher.NULL_UUID;
Overlays.keyboardFocusOverlay = Uuid.NULL;
Entities.keyboardFocusEntity = touchTarget.entityID;
} else if (touchTarget.overlayID && touchTarget.overlayID !== controllerDispatcher.NULL_UUID) {
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NULL) {
Overlays.keyboardFocusOverlay = touchTarget.overlayID;
Entities.keyboardFocusEntity = controllerDispatcher.NULL_UUID;
Entities.keyboardFocusEntity = Uuid.NULL;
}
}
@ -42,9 +42,9 @@ function sendHoverEnterEventToTouchTarget(hand, touchTarget) {
button: "None"
};
if (touchTarget.entityID && touchTarget.entityID !== controllerDispatcher.NULL_UUID) {
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NULL) {
Entities.sendHoverEnterEntity(touchTarget.entityID, pointerEvent);
} else if (touchTarget.overlayID && touchTarget.overlayID !== controllerDispatcher.NULL_UUID) {
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NULL) {
Overlays.sendHoverEnterOverlay(touchTarget.overlayID, pointerEvent);
}
}
@ -60,10 +60,10 @@ function sendHoverOverEventToTouchTarget(hand, touchTarget) {
button: "None"
};
if (touchTarget.entityID && touchTarget.entityID !== controllerDispatcher.NULL_UUID) {
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NULL) {
Entities.sendMouseMoveOnEntity(touchTarget.entityID, pointerEvent);
Entities.sendHoverOverEntity(touchTarget.entityID, pointerEvent);
} else if (touchTarget.overlayID && touchTarget.overlayID !== controllerDispatcher.NULL_UUID) {
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NULL) {
Overlays.sendMouseMoveOnOverlay(touchTarget.overlayID, pointerEvent);
Overlays.sendHoverOverOverlay(touchTarget.overlayID, pointerEvent);
}
@ -81,10 +81,10 @@ function sendTouchStartEventToTouchTarget(hand, touchTarget) {
isPrimaryHeld: true
};
if (touchTarget.entityID && touchTarget.entityID !== controllerDispatcher.NULL_UUID) {
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NULL) {
Entities.sendMousePressOnEntity(touchTarget.entityID, pointerEvent);
Entities.sendClickDownOnEntity(touchTarget.entityID, pointerEvent);
} else if (touchTarget.overlayID && touchTarget.overlayID !== controllerDispatcher.NULL_UUID) {
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NULL) {
Overlays.sendMousePressOnOverlay(touchTarget.overlayID, pointerEvent);
}
}
@ -100,11 +100,11 @@ function sendTouchEndEventToTouchTarget(hand, touchTarget) {
button: "Primary"
};
if (touchTarget.entityID && touchTarget.entityID !== controllerDispatcher.NULL_UUID) {
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NULL) {
Entities.sendMouseReleaseOnEntity(touchTarget.entityID, pointerEvent);
Entities.sendClickReleaseOnEntity(touchTarget.entityID, pointerEvent);
Entities.sendHoverLeaveEntity(touchTarget.entityID, pointerEvent);
} else if (touchTarget.overlayID && touchTarget.overlayID !== controllerDispatcher.NULL_UUID) {
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NULL) {
Overlays.sendMouseReleaseOnOverlay(touchTarget.overlayID, pointerEvent);
}
}
@ -121,10 +121,10 @@ function sendTouchMoveEventToTouchTarget(hand, touchTarget) {
isPrimaryHeld: true
};
if (touchTarget.entityID && touchTarget.entityID !== controllerDispatcher.NULL_UUID) {
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NULL) {
Entities.sendMouseMoveOnEntity(touchTarget.entityID, pointerEvent);
Entities.sendHoldingClickOnEntity(touchTarget.entityID, pointerEvent);
} else if (touchTarget.overlayID && touchTarget.overlayID !== controllerDispatcher.NULL_UUID) {
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NULL) {
Overlays.sendMouseMoveOnOverlay(touchTarget.overlayID, pointerEvent);
}
}

View file

@ -13,7 +13,6 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
const CLIENTONLY = false;
const NULL_UUID = "{00000000-0000-0000-0000-000000000000}";
const ENTITY_CHECK_INTERVAL = 5000; // ms = 5 seconds
const STARTUP_DELAY = 2000; // ms = 2 second
const OLD_AGE = 3500; // we recreate the entity if older than this time in seconds
@ -24,7 +23,7 @@ const SIZE_Y = 0.075;
const LETTER_OFFSET = 0.03; // arbitrary value to dynamically change width, could be more accurate by detecting characters
const LINE_HEIGHT = 0.05;
var nameTagEntityID = NULL_UUID;
var nameTagEntityID = Uuid.NULL;
var lastCheckForEntity = 0;
// create the name tag entity after a brief delay
@ -62,9 +61,9 @@ function updateNameTag() {
};
function deleteNameTag() {
if(nameTagEntityID !== NULL_UUID) {
if(nameTagEntityID !== Uuid.NULL) {
Entities.deleteEntity(nameTagEntityID);
nameTagEntityID = NULL_UUID;
nameTagEntityID = Uuid.NULL;
}
}
@ -85,7 +84,7 @@ function cleanup() {
Script.update.connect(update);
function update() {
// if no entity we return
if(nameTagEntityID == NULL_UUID) {
if(nameTagEntityID == Uuid.NULL) {
return;
}

View file

@ -576,7 +576,7 @@
createNotification("Processing GIF snapshot...", NotificationType.SNAPSHOT);
}
function processingGif() {
function walletNotSetup() {
createNotification("Your wallet isn't set up. Open the WALLET app.", NotificationType.WALLET);
}

View file

@ -14,7 +14,6 @@
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
var NULL_UUID = "{00000000-0000-0000-0000-000000000000}";
var LIFETIME = 3600;
var BALL_SIZE = 0.175;
var BALL_DAMPING = 0.5;

View file

@ -27,6 +27,7 @@ if (typeof Vec3.abs !== "function") {
}
if (typeof Quat.ZERO !== "object") {
// TODO: Change to Quat.IDENTITY.
Quat.ZERO = Quat.fromVec3Radians(Vec3.ZERO);
}