mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 14:03:55 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into virtualBaton
This commit is contained in:
commit
61393818fe
30 changed files with 721 additions and 238 deletions
|
@ -551,7 +551,9 @@ void AudioMixer::handleNodeAudioPacket(QSharedPointer<ReceivedMessage> message,
|
|||
void AudioMixer::handleMuteEnvironmentPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
if (sendingNode->getCanAdjustLocks()) {
|
||||
if (sendingNode->isAllowedEditor()) {
|
||||
qDebug() << "Received a mute environment packet of" << message->getSize() << "bytes";
|
||||
|
||||
auto newPacket = NLPacket::create(PacketType::MuteEnvironment, message->getSize());
|
||||
// Copy payload
|
||||
newPacket->write(message->getRawMessage(), message->getSize());
|
||||
|
|
|
@ -155,7 +155,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo
|
|||
_pendingAssignedNodes.erase(it);
|
||||
|
||||
// always allow assignment clients to create and destroy entities
|
||||
newNode->setCanAdjustLocks(true);
|
||||
newNode->setIsAllowedEditor(true);
|
||||
newNode->setCanRez(true);
|
||||
|
||||
return newNode;
|
||||
|
@ -219,13 +219,13 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
|
|||
}
|
||||
}
|
||||
|
||||
// if this user is in the editors list (or if the editors list is empty) set the user's node's canAdjustLocks to true
|
||||
// if this user is in the editors list (or if the editors list is empty) set the user's node's isAllowedEditor to true
|
||||
const QVariant* allowedEditorsVariant =
|
||||
valueForKeyPath(_server->_settingsManager.getSettingsMap(), ALLOWED_EDITORS_SETTINGS_KEYPATH);
|
||||
QStringList allowedEditors = allowedEditorsVariant ? allowedEditorsVariant->toStringList() : QStringList();
|
||||
|
||||
// if the allowed editors list is empty then everyone can adjust locks
|
||||
bool canAdjustLocks = allowedEditors.empty();
|
||||
bool isAllowedEditor = allowedEditors.empty();
|
||||
|
||||
if (allowedEditors.contains(username, Qt::CaseInsensitive)) {
|
||||
// we have a non-empty allowed editors list - check if this user is verified to be in it
|
||||
|
@ -238,10 +238,10 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
|
|||
<< "will be given edit rights to avoid a thrasing of public key requests and connect requests.";
|
||||
}
|
||||
|
||||
canAdjustLocks = true;
|
||||
isAllowedEditor = true;
|
||||
} else {
|
||||
// already verified this user and they are in the allowed editors list
|
||||
canAdjustLocks = true;
|
||||
isAllowedEditor = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,14 +256,14 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
|
|||
|
||||
bool canRez = true;
|
||||
if (onlyEditorsAreRezzers) {
|
||||
canRez = canAdjustLocks;
|
||||
canRez = isAllowedEditor;
|
||||
}
|
||||
|
||||
// add the new node
|
||||
SharedNodePointer newNode = addVerifiedNodeFromConnectRequest(nodeConnection);
|
||||
|
||||
// set the edit rights for this user
|
||||
newNode->setCanAdjustLocks(canAdjustLocks);
|
||||
newNode->setIsAllowedEditor(isAllowedEditor);
|
||||
newNode->setCanRez(canRez);
|
||||
|
||||
// grab the linked data for our new node so we can set the username
|
||||
|
|
|
@ -744,7 +744,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
|||
|
||||
extendedHeaderStream << limitedNodeList->getSessionUUID();
|
||||
extendedHeaderStream << node->getUUID();
|
||||
extendedHeaderStream << (quint8) node->getCanAdjustLocks();
|
||||
extendedHeaderStream << (quint8) node->isAllowedEditor();
|
||||
extendedHeaderStream << (quint8) node->getCanRez();
|
||||
|
||||
auto domainListPackets = NLPacketList::create(PacketType::DomainList, extendedHeader);
|
||||
|
|
|
@ -39,10 +39,10 @@ var lightOverlayManager = new LightOverlayManager();
|
|||
var cameraManager = new CameraManager();
|
||||
|
||||
var grid = Grid();
|
||||
gridTool = GridTool({
|
||||
horizontalGrid: grid
|
||||
});
|
||||
gridTool.setVisible(false);
|
||||
// gridTool = GridTool({
|
||||
// horizontalGrid: grid
|
||||
// });
|
||||
// gridTool.setVisible(false);
|
||||
|
||||
var entityListTool = EntityListTool();
|
||||
|
||||
|
@ -336,7 +336,7 @@ var toolBar = (function() {
|
|||
isActive = active;
|
||||
if (!isActive) {
|
||||
entityListTool.setVisible(false);
|
||||
gridTool.setVisible(false);
|
||||
// gridTool.setVisible(false);
|
||||
grid.setEnabled(false);
|
||||
propertiesTool.setVisible(false);
|
||||
selectionManager.clearSelections();
|
||||
|
@ -344,7 +344,7 @@ var toolBar = (function() {
|
|||
} else {
|
||||
hasShownPropertiesTool = false;
|
||||
entityListTool.setVisible(true);
|
||||
gridTool.setVisible(true);
|
||||
// gridTool.setVisible(true);
|
||||
grid.setEnabled(true);
|
||||
propertiesTool.setVisible(true);
|
||||
Window.setFocus();
|
||||
|
|
|
@ -15,6 +15,8 @@ var TEST_MODEL_URL = 'https://s3.amazonaws.com/hifi-public/ozan/avatars/albert/a
|
|||
|
||||
var doppelgangers = [];
|
||||
|
||||
var MIRROR_JOINT_DATA = true;
|
||||
|
||||
function Doppelganger(avatar) {
|
||||
this.initialProperties = {
|
||||
name: 'Hifi-Doppelganger',
|
||||
|
@ -41,24 +43,248 @@ function getJointData(avatar) {
|
|||
index: index,
|
||||
translation: translation,
|
||||
rotation: rotation
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
return allJointData;
|
||||
}
|
||||
|
||||
function setJointData(doppelganger, allJointData) {
|
||||
function setJointData(doppelganger, relativeXforms) {
|
||||
var jointRotations = [];
|
||||
allJointData.forEach(function(jointData, index) {
|
||||
jointRotations.push(jointData.rotation);
|
||||
});
|
||||
var i, l = relativeXforms.length;
|
||||
for (i = 0; i < l; i++) {
|
||||
jointRotations.push(relativeXforms[i].rot);
|
||||
}
|
||||
Entities.setAbsoluteJointRotationsInObjectFrame(doppelganger.id, jointRotations);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function mirrorJointData() {
|
||||
return mirroredJointData;
|
||||
// maps joint names to their mirrored joint
|
||||
var JOINT_MIRROR_NAME_MAP = {
|
||||
RightUpLeg: "LeftUpLeg",
|
||||
RightLeg: "LeftLeg",
|
||||
RightFoot: "LeftFoot",
|
||||
LeftUpLeg: "RightUpLeg",
|
||||
LeftLeg: "RightLeg",
|
||||
LeftFoot: "RightFoot",
|
||||
RightShoulder: "LeftShoulder",
|
||||
RightArm: "LeftArm",
|
||||
RightForeArm: "LeftForeArm",
|
||||
RightHand: "LeftHand",
|
||||
RightHandThumb1: "LeftHandThumb1",
|
||||
RightHandThumb2: "LeftHandThumb2",
|
||||
RightHandThumb3: "LeftHandThumb3",
|
||||
RightHandThumb4: "LeftHandThumb4",
|
||||
RightHandIndex1: "LeftHandIndex1",
|
||||
RightHandIndex2: "LeftHandIndex2",
|
||||
RightHandIndex3: "LeftHandIndex3",
|
||||
RightHandIndex4: "LeftHandIndex4",
|
||||
RightHandMiddle1: "LeftHandMiddle1",
|
||||
RightHandMiddle2: "LeftHandMiddle2",
|
||||
RightHandMiddle3: "LeftHandMiddle3",
|
||||
RightHandMiddle4: "LeftHandMiddle4",
|
||||
RightHandRing1: "LeftHandRing1",
|
||||
RightHandRing2: "LeftHandRing2",
|
||||
RightHandRing3: "LeftHandRing3",
|
||||
RightHandRing4: "LeftHandRing4",
|
||||
RightHandPinky1: "LeftHandPinky1",
|
||||
RightHandPinky2: "LeftHandPinky2",
|
||||
RightHandPinky3: "LeftHandPinky3",
|
||||
RightHandPinky4: "LeftHandPinky4",
|
||||
LeftShoulder: "RightShoulder",
|
||||
LeftArm: "RightArm",
|
||||
LeftForeArm: "RightForeArm",
|
||||
LeftHand: "RightHand",
|
||||
LeftHandThumb1: "RightHandThumb1",
|
||||
LeftHandThumb2: "RightHandThumb2",
|
||||
LeftHandThumb3: "RightHandThumb3",
|
||||
LeftHandThumb4: "RightHandThumb4",
|
||||
LeftHandIndex1: "RightHandIndex1",
|
||||
LeftHandIndex2: "RightHandIndex2",
|
||||
LeftHandIndex3: "RightHandIndex3",
|
||||
LeftHandIndex4: "RightHandIndex4",
|
||||
LeftHandMiddle1: "RightHandMiddle1",
|
||||
LeftHandMiddle2: "RightHandMiddle2",
|
||||
LeftHandMiddle3: "RightHandMiddle3",
|
||||
LeftHandMiddle4: "RightHandMiddle4",
|
||||
LeftHandRing1: "RightHandRing1",
|
||||
LeftHandRing2: "RightHandRing2",
|
||||
LeftHandRing3: "RightHandRing3",
|
||||
LeftHandRing4: "RightHandRing4",
|
||||
LeftHandPinky1: "RightHandPinky1",
|
||||
LeftHandPinky2: "RightHandPinky2",
|
||||
LeftHandPinky3: "RightHandPinky3",
|
||||
LeftHandPinky4: "RightHandPinky4",
|
||||
LeftHandPinky: "RightHandPinky",
|
||||
};
|
||||
|
||||
// maps joint names to parent joint names.
|
||||
var JOINT_PARENT_NAME_MAP = {
|
||||
Hips: "",
|
||||
RightUpLeg: "Hips",
|
||||
RightLeg: "RightUpLeg",
|
||||
RightFoot: "RightLeg",
|
||||
LeftUpLeg: "Hips",
|
||||
LeftLeg: "LeftUpLeg",
|
||||
LeftFoot: "LeftLeg",
|
||||
Spine: "Hips",
|
||||
Spine1: "Spine",
|
||||
Spine2: "Spine1",
|
||||
Spine3: "Spine2",
|
||||
Neck: "Spine3",
|
||||
Head: "Neck",
|
||||
RightShoulder: "Spine3",
|
||||
RightArm: "RightShoulder",
|
||||
RightForeArm: "RightArm",
|
||||
RightHand: "RightForeArm",
|
||||
RightHandThumb1: "RightHand",
|
||||
RightHandThumb2: "RightHandThumb1",
|
||||
RightHandThumb3: "RightHandThumb2",
|
||||
RightHandThumb4: "RightHandThumb3",
|
||||
RightHandIndex1: "RightHand",
|
||||
RightHandIndex2: "RightHandIndex1",
|
||||
RightHandIndex3: "RightHandIndex2",
|
||||
RightHandIndex4: "RightHandIndex3",
|
||||
RightHandMiddle1: "RightHand",
|
||||
RightHandMiddle2: "RightHandMiddle1",
|
||||
RightHandMiddle3: "RightHandMiddle2",
|
||||
RightHandMiddle4: "RightHandMiddle3",
|
||||
RightHandRing1: "RightHand",
|
||||
RightHandRing2: "RightHandRing1",
|
||||
RightHandRing3: "RightHandRing2",
|
||||
RightHandRing4: "RightHandRing3",
|
||||
RightHandPinky1: "RightHand",
|
||||
RightHandPinky2: "RightHandPinky1",
|
||||
RightHandPinky3: "RightHandPinky2",
|
||||
RightHandPinky4: "RightHandPinky3",
|
||||
LeftShoulder: "Spine3",
|
||||
LeftArm: "LeftShoulder",
|
||||
LeftForeArm: "LeftArm",
|
||||
LeftHand: "LeftForeArm",
|
||||
LeftHandThumb1: "LeftHand",
|
||||
LeftHandThumb2: "LeftHandThumb1",
|
||||
LeftHandThumb3: "LeftHandThumb2",
|
||||
LeftHandThumb4: "LeftHandThumb3",
|
||||
LeftHandIndex1: "LeftHand",
|
||||
LeftHandIndex2: "LeftHandIndex1",
|
||||
LeftHandIndex3: "LeftHandIndex2",
|
||||
LeftHandIndex4: "LeftHandIndex3",
|
||||
LeftHandMiddle1: "LeftHand",
|
||||
LeftHandMiddle2: "LeftHandMiddle1",
|
||||
LeftHandMiddle3: "LeftHandMiddle2",
|
||||
LeftHandMiddle4: "LeftHandMiddle3",
|
||||
LeftHandRing1: "LeftHand",
|
||||
LeftHandRing2: "LeftHandRing1",
|
||||
LeftHandRing3: "LeftHandRing2",
|
||||
LeftHandRing4: "LeftHandRing3",
|
||||
LeftHandPinky1: "LeftHand",
|
||||
LeftHandPinky2: "LeftHandPinky1",
|
||||
LeftHandPinky3: "LeftHandPinky2",
|
||||
LeftHandPinky: "LeftHandPinky3",
|
||||
};
|
||||
|
||||
// maps joint indices to parent joint indices.
|
||||
var JOINT_PARENT_INDEX_MAP;
|
||||
var JOINT_MIRROR_INDEX_MAP;
|
||||
|
||||
// ctor
|
||||
function Xform(rot, pos) {
|
||||
this.rot = rot;
|
||||
this.pos = pos;
|
||||
};
|
||||
Xform.ident = function () {
|
||||
return new Xform({x: 0, y: 0, z: 0, w: 1}, {x: 0, y: 0, z: 0});
|
||||
}
|
||||
Xform.mul = function (lhs, rhs) {
|
||||
var rot = Quat.multiply(lhs.rot, rhs.rot);
|
||||
var pos = Vec3.sum(lhs.pos, Vec3.multiplyQbyV(lhs.rot, rhs.pos));
|
||||
return new Xform(rot, pos);
|
||||
};
|
||||
Xform.prototype.inv = function () {
|
||||
var invRot = Quat.inverse(this.rot);
|
||||
var invPos = Vec3.multiply(-1, this.pos);
|
||||
return new Xform(invRot, Vec3.multiplyQbyV(invRot, invPos));
|
||||
};
|
||||
Xform.prototype.mirrorX = function () {
|
||||
return new Xform({x: this.rot.x, y: -this.rot.y, z: -this.rot.z, w: this.rot.w},
|
||||
{x: -this.pos.x, y: this.pos.y, z: this.pos.z});
|
||||
}
|
||||
Xform.prototype.toString = function () {
|
||||
var rot = this.rot;
|
||||
var pos = this.pos;
|
||||
return "Xform rot = (" + rot.x + ", " + rot.y + ", " + rot.z + ", " + rot.w + "), pos = (" + pos.x + ", " + pos.y + ", " + pos.z + ")";
|
||||
};
|
||||
|
||||
function buildAbsoluteXformsFromMyAvatar() {
|
||||
var jointNames = MyAvatar.getJointNames();
|
||||
|
||||
// lazy init of JOINT_PARENT_INDEX_MAP
|
||||
if (jointNames.length > 0 && !JOINT_PARENT_INDEX_MAP) {
|
||||
JOINT_PARENT_INDEX_MAP = {};
|
||||
var keys = Object.keys(JOINT_PARENT_NAME_MAP);
|
||||
var i, l = keys.length;
|
||||
var keyIndex, valueName, valueIndex;
|
||||
for (i = 0; i < l; i++) {
|
||||
keyIndex = MyAvatar.getJointIndex(keys[i]);
|
||||
valueName = JOINT_PARENT_NAME_MAP[keys[i]];
|
||||
if (valueName) {
|
||||
valueIndex = MyAvatar.getJointIndex(valueName);
|
||||
} else {
|
||||
valueIndex = -1;
|
||||
}
|
||||
JOINT_PARENT_INDEX_MAP[keyIndex] = valueIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// lazy init of JOINT_MIRROR_INDEX_MAP
|
||||
if (jointNames.length > 0 && !JOINT_MIRROR_INDEX_MAP) {
|
||||
JOINT_MIRROR_INDEX_MAP = {};
|
||||
var keys = Object.keys(JOINT_MIRROR_NAME_MAP);
|
||||
var i, l = keys.length;
|
||||
var keyIndex, valueName, valueIndex;
|
||||
for (i = 0; i < l; i++) {
|
||||
keyIndex = MyAvatar.getJointIndex(keys[i]);
|
||||
valueIndex = MyAvatar.getJointIndex(JOINT_MIRROR_NAME_MAP[keys[i]]);
|
||||
if (valueIndex > 0) {
|
||||
JOINT_MIRROR_INDEX_MAP[keyIndex] = valueIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build absolute xforms by multiplying by parent Xforms
|
||||
var absoluteXforms = [];
|
||||
var i, l = jointNames.length;
|
||||
var parentXform;
|
||||
for (i = 0; i < l; i++) {
|
||||
var parentIndex = JOINT_PARENT_INDEX_MAP[i];
|
||||
if (parentIndex >= 0) {
|
||||
parentXform = absoluteXforms[parentIndex];
|
||||
} else {
|
||||
parentXform = Xform.ident();
|
||||
}
|
||||
var localXform = new Xform(MyAvatar.getJointRotation(i), MyAvatar.getJointTranslation(i));
|
||||
absoluteXforms.push(Xform.mul(parentXform, localXform));
|
||||
}
|
||||
return absoluteXforms;
|
||||
}
|
||||
|
||||
function buildRelativeXformsFromAbsoluteXforms(absoluteXforms) {
|
||||
|
||||
// build relative xforms by multiplying by the inverse of the parent Xforms
|
||||
var relativeXforms = [];
|
||||
var i, l = absoluteXforms.length;
|
||||
var parentXform;
|
||||
for (i = 0; i < l; i++) {
|
||||
var parentIndex = JOINT_PARENT_INDEX_MAP[i];
|
||||
if (parentIndex >= 0) {
|
||||
parentXform = absoluteXforms[parentIndex];
|
||||
} else {
|
||||
parentXform = Xform.ident();
|
||||
}
|
||||
relativeXforms.push(Xform.mul(parentXform.inv(), absoluteXforms[i]));
|
||||
}
|
||||
return relativeXforms;
|
||||
}
|
||||
|
||||
function createDoppelganger(avatar) {
|
||||
|
@ -95,10 +321,22 @@ function disconnectDoppelgangerUpdates() {
|
|||
}
|
||||
|
||||
function updateDoppelganger() {
|
||||
var absoluteXforms = buildAbsoluteXformsFromMyAvatar();
|
||||
if (MIRROR_JOINT_DATA) {
|
||||
var mirroredAbsoluteXforms = [];
|
||||
var i, l = absoluteXforms.length;
|
||||
for (i = 0; i < l; i++) {
|
||||
var mirroredIndex = JOINT_MIRROR_INDEX_MAP[i];
|
||||
if (mirroredIndex === undefined) {
|
||||
mirroredIndex = i;
|
||||
}
|
||||
mirroredAbsoluteXforms[mirroredIndex] = absoluteXforms[i].mirrorX();
|
||||
}
|
||||
absoluteXforms = mirroredAbsoluteXforms;
|
||||
}
|
||||
var relativeXforms = buildRelativeXformsFromAbsoluteXforms(absoluteXforms);
|
||||
doppelgangers.forEach(function(doppelganger) {
|
||||
var joints = getJointData(MyAvatar);
|
||||
//var mirroredJoints = mirrorJointData(joints);
|
||||
setJointData(doppelganger, joints);
|
||||
setJointData(doppelganger, relativeXforms);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -111,7 +349,7 @@ function makeDoppelgangerForMyAvatar() {
|
|||
makeDoppelgangerForMyAvatar();
|
||||
|
||||
function cleanup() {
|
||||
disconnectDoppelgangerUpdates();
|
||||
//disconnectDoppelgangerUpdates();
|
||||
|
||||
doppelgangers.forEach(function(doppelganger) {
|
||||
Entities.deleteEntity(doppelganger.id);
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
function createEmitNumberPropertyUpdateFunction(propertyName) {
|
||||
return function() {
|
||||
EventBridge.emitWebEvent(
|
||||
'{ "type":"update", "properties":{"' + propertyName + '":' + this.value + '}}'
|
||||
'{ "type":"update", "properties":{"' + propertyName + '":' + parseFloat(this.value).toFixed(2) + '}}'
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ Windows.Window {
|
|||
closable: true
|
||||
visible: false
|
||||
width: 384; height: 640;
|
||||
title: "Tools"
|
||||
property string newTabSource
|
||||
property alias tabView: tabView
|
||||
onParentChanged: {
|
||||
|
|
|
@ -1,21 +1,54 @@
|
|||
import QtQuick 2.3
|
||||
import QtQuick.Controls 1.3 as Original
|
||||
import QtQuick.Controls.Styles 1.3 as OriginalStyles
|
||||
|
||||
import "."
|
||||
import "../styles"
|
||||
|
||||
Original.Button {
|
||||
id: root
|
||||
property color iconColor: "black"
|
||||
FontLoader { id: iconFont; source: "../../fonts/fontawesome-webfont.ttf"; }
|
||||
style: OriginalStyles.ButtonStyle {
|
||||
label: Text {
|
||||
renderType: Text.NativeRendering
|
||||
property real size: 32
|
||||
SystemPalette { id: palette; colorGroup: SystemPalette.Active }
|
||||
SystemPalette { id: disabledPalette; colorGroup: SystemPalette.Disabled }
|
||||
style: OriginalStyles.ButtonStyle {
|
||||
label: FontAwesome {
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.family: iconFont.name
|
||||
font.pointSize: 20
|
||||
color: control.enabled ? control.iconColor : "gray"
|
||||
font.pixelSize: control.size - 4
|
||||
color: control.enabled ? palette.buttonText : disabledPalette.buttonText
|
||||
text: control.text
|
||||
}
|
||||
}
|
||||
background: Rectangle {
|
||||
id: background
|
||||
implicitWidth: size
|
||||
implicitHeight: size
|
||||
border.width: 1
|
||||
border.color: "black"
|
||||
radius: 4
|
||||
color: control.enabled ? palette.button : disabledPalette.button
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
onActiveFocusChanged: {
|
||||
if (control.activeFocus) {
|
||||
pulseAnimation.restart();
|
||||
} else {
|
||||
pulseAnimation.stop();
|
||||
}
|
||||
background.border.width = 1;
|
||||
}
|
||||
}
|
||||
|
||||
SequentialAnimation {
|
||||
id: pulseAnimation;
|
||||
running: false
|
||||
NumberAnimation { target: border; property: "width"; to: 3; duration: 500 }
|
||||
NumberAnimation { target: border; property: "width"; to: 1; duration: 500 }
|
||||
onStopped: if (control.activeFocus) { start(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
Keys.onEnterPressed: root.clicked();
|
||||
Keys.onReturnPressed: root.clicked();
|
||||
}
|
||||
|
|
|
@ -230,19 +230,23 @@ FocusScope {
|
|||
return;
|
||||
}
|
||||
|
||||
var windowRect = targetWindow.framedRect();
|
||||
var minPosition = Qt.vector2d(-windowRect.x, -windowRect.y);
|
||||
var maxPosition = Qt.vector2d(desktop.width - windowRect.width, desktop.height - windowRect.height);
|
||||
var newPosition = Qt.vector2d(targetWindow.x, targetWindow.y);
|
||||
if (newPosition.x === -1 && newPosition.y === -1) {
|
||||
// Set initial window position
|
||||
// newPosition = Utils.randomPosition(minPosition, maxPosition);
|
||||
console.log("Target has no defined position, putting in center of the screen")
|
||||
newPosition = Qt.vector2d(desktop.width / 2 - windowRect.width / 2,
|
||||
desktop.height / 2 - windowRect.height / 2);
|
||||
// If the window is completely offscreen, reposition it
|
||||
if ((targetWindow.x > desktop.width || (targetWindow.x + targetWindow.width) < 0) ||
|
||||
(targetWindow.y > desktop.height || (targetWindow.y + targetWindow.height) < 0)) {
|
||||
newPosition.x = -1
|
||||
newPosition.y = -1
|
||||
}
|
||||
|
||||
newPosition = Utils.clampVector(newPosition, minPosition, maxPosition);
|
||||
if (newPosition.x === -1 && newPosition.y === -1) {
|
||||
// Set initial window position
|
||||
// var minPosition = Qt.vector2d(-windowRect.x, -windowRect.y);
|
||||
// var maxPosition = Qt.vector2d(desktop.width - windowRect.width, desktop.height - windowRect.height);
|
||||
// newPosition = Utils.clampVector(newPosition, minPosition, maxPosition);
|
||||
// newPosition = Utils.randomPosition(minPosition, maxPosition);
|
||||
newPosition = Qt.vector2d(desktop.width / 2 - targetWindow.width / 2,
|
||||
desktop.height / 2 - targetWindow.height / 2);
|
||||
}
|
||||
targetWindow.x = newPosition.x;
|
||||
targetWindow.y = newPosition.y;
|
||||
}
|
||||
|
|
|
@ -55,35 +55,39 @@ ModalWindow {
|
|||
anchors { left: parent.left; top: parent.top; margins: 8 }
|
||||
spacing: 8
|
||||
// FIXME implement back button
|
||||
// VrControls.FontAwesome {
|
||||
// id: backButton
|
||||
// text: "\uf0a8"
|
||||
// size: currentDirectory.height
|
||||
// enabled: d.backStack.length != 0
|
||||
// MouseArea { anchors.fill: parent; onClicked: d.navigateBack() }
|
||||
// }
|
||||
VrControls.FontAwesome {
|
||||
//VrControls.ButtonAwesome {
|
||||
// id: backButton
|
||||
// text: "\uf0a8"
|
||||
// size: currentDirectory.height
|
||||
// enabled: d.backStack.length != 0
|
||||
// MouseArea { anchors.fill: parent; onClicked: d.navigateBack() }
|
||||
//}
|
||||
VrControls.ButtonAwesome {
|
||||
id: upButton
|
||||
enabled: model.parentFolder && model.parentFolder !== ""
|
||||
text: "\uf0aa"
|
||||
size: currentDirectory.height
|
||||
color: enabled ? "black" : "gray"
|
||||
MouseArea { anchors.fill: parent; onClicked: d.navigateUp() }
|
||||
size: 32
|
||||
onClicked: d.navigateUp();
|
||||
}
|
||||
VrControls.FontAwesome {
|
||||
VrControls.ButtonAwesome {
|
||||
id: homeButton
|
||||
property var destination: helper.home();
|
||||
visible: destination ? true : false
|
||||
enabled: d.homeDestination ? true : false
|
||||
text: "\uf015"
|
||||
size: currentDirectory.height
|
||||
MouseArea { anchors.fill: parent; onClicked: model.folder = parent.destination }
|
||||
size: 32
|
||||
onClicked: d.navigateHome();
|
||||
}
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: currentDirectory
|
||||
height: homeButton.height
|
||||
anchors { left: navControls.right; right: parent.right; top: parent.top; margins: 8 }
|
||||
property var lastValidFolder: helper.urlToPath(model.folder)
|
||||
onLastValidFolderChanged: text = lastValidFolder;
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pointSize: 14
|
||||
font.bold: true
|
||||
|
||||
// FIXME add support auto-completion
|
||||
onAccepted: {
|
||||
|
@ -93,7 +97,6 @@ ModalWindow {
|
|||
}
|
||||
model.folder = helper.pathToUrl(text);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QtObject {
|
||||
|
@ -104,6 +107,7 @@ ModalWindow {
|
|||
property var backStack: []
|
||||
property var tableViewConnection: Connections { target: fileTableView; onCurrentRowChanged: d.update(); }
|
||||
property var modelConnection: Connections { target: model; onFolderChanged: d.update(); }
|
||||
property var homeDestination: helper.home();
|
||||
Component.onCompleted: update();
|
||||
|
||||
function update() {
|
||||
|
@ -127,12 +131,20 @@ ModalWindow {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function navigateHome() {
|
||||
model.folder = homeDestination;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FileTableView {
|
||||
id: fileTableView
|
||||
anchors { left: parent.left; right: parent.right; top: currentDirectory.bottom; bottom: currentSelection.top; margins: 8 }
|
||||
onDoubleClicked: navigateToRow(row);
|
||||
focus: true
|
||||
Keys.onReturnPressed: navigateToCurrentRow();
|
||||
Keys.onEnterPressed: navigateToCurrentRow();
|
||||
model: FolderListModel {
|
||||
id: model
|
||||
nameFilters: selectionType.currentFilter
|
||||
|
@ -146,6 +158,7 @@ ModalWindow {
|
|||
upButton.enabled = Qt.binding(function() { return (model.parentFolder && model.parentFolder != "") ? true : false; });
|
||||
showFiles = !root.selectDirectory
|
||||
}
|
||||
onFolderChanged: fileTableView.currentRow = 0;
|
||||
}
|
||||
|
||||
function navigateToRow(row) {
|
||||
|
@ -159,10 +172,9 @@ ModalWindow {
|
|||
var file = model.get(row, "fileURL");
|
||||
if (isFolder) {
|
||||
fileTableView.model.folder = file
|
||||
currentRow = -1;
|
||||
} else {
|
||||
root.selectedFile(file);
|
||||
root.visible = false;
|
||||
root.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,6 +183,7 @@ ModalWindow {
|
|||
id: currentSelection
|
||||
anchors { right: root.selectDirectory ? parent.right : selectionType.left; rightMargin: 8; left: parent.left; leftMargin: 8; top: selectionType.top }
|
||||
readOnly: true
|
||||
activeFocusOnTab: false
|
||||
}
|
||||
|
||||
FileTypeSelection {
|
||||
|
@ -187,17 +200,7 @@ ModalWindow {
|
|||
anchors.rightMargin: 8
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 8
|
||||
layoutDirection: Qt.RightToLeft
|
||||
spacing: 8
|
||||
Button {
|
||||
id: cancelButton
|
||||
text: "Cancel"
|
||||
KeyNavigation.up: selectionType
|
||||
KeyNavigation.left: openButton
|
||||
KeyNavigation.right: fileTableView.contentItem
|
||||
Keys.onReturnPressed: { canceled(); root.enabled = false }
|
||||
onClicked: { canceled(); root.visible = false; }
|
||||
}
|
||||
Button {
|
||||
id: openButton
|
||||
text: root.selectDirectory ? "Choose" : "Open"
|
||||
|
@ -209,12 +212,28 @@ ModalWindow {
|
|||
KeyNavigation.left: selectionType
|
||||
KeyNavigation.right: cancelButton
|
||||
}
|
||||
Button {
|
||||
id: cancelButton
|
||||
text: "Cancel"
|
||||
KeyNavigation.up: selectionType
|
||||
KeyNavigation.left: openButton
|
||||
KeyNavigation.right: fileTableView.contentItem
|
||||
Keys.onReturnPressed: { canceled(); root.enabled = false }
|
||||
onClicked: { canceled(); root.visible = false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Backspace && d.navigateUp()) {
|
||||
event.accepted = true
|
||||
switch (event.key) {
|
||||
case Qt.Key_Backspace:
|
||||
event.accepted = d.navigateUp();
|
||||
break;
|
||||
|
||||
case Qt.Key_Home:
|
||||
event.accepted = d.navigateHome();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ ModalWindow {
|
|||
|
||||
VrControls.ComboBox {
|
||||
id: comboBox
|
||||
focus: items ? true : false
|
||||
focus: true
|
||||
visible: items ? true : false
|
||||
anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter }
|
||||
model: items ? items : []
|
||||
|
|
|
@ -10,7 +10,7 @@ TableView {
|
|||
Text {
|
||||
x: 3
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: root.activeFocus && styleData.row === root.currentRow ? "yellow" : styleData.textColor
|
||||
color: styleData.textColor
|
||||
elide: styleData.elideMode
|
||||
text: getText();
|
||||
font.italic: root.model.get(styleData.row, "fileIsDir") ? true : false
|
||||
|
|
|
@ -7,7 +7,7 @@ PreferencesDialog {
|
|||
id: root
|
||||
objectName: "AvatarPreferencesDialog"
|
||||
title: "Avatar Preferences"
|
||||
showCategories: [ "Avatar Basics", "Avatar Tuning" ]
|
||||
showCategories: [ "Avatar Basics", "Avatar Tuning", "Avatar Camera" ]
|
||||
property var settings: Settings {
|
||||
category: root.objectName
|
||||
property alias x: root.x
|
||||
|
|
|
@ -54,10 +54,10 @@ Frame {
|
|||
Text {
|
||||
id: titleText
|
||||
anchors { left: parent.left; leftMargin: iconSize; right: controlsRow.left; rightMargin: iconSize; top: parent.top; topMargin: iconSize / 2; }
|
||||
text: window.title
|
||||
text: window ? window.title : ""
|
||||
elide: Text.ElideRight
|
||||
font.bold: true
|
||||
color: window.focus ? "white" : "gray"
|
||||
color: (window && window.focus) ? "white" : "gray"
|
||||
style: Text.Outline;
|
||||
styleColor: "black"
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ Item {
|
|||
id: debugZ
|
||||
visible: DebugQML
|
||||
text: window ? "Z: " + window.z : ""
|
||||
y: window.height + 4
|
||||
y: window ? window.height + 4 : 0
|
||||
}
|
||||
|
||||
function deltaSize(dx, dy) {
|
||||
|
|
|
@ -6,23 +6,31 @@ import "../controls"
|
|||
Frame {
|
||||
id: frame
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
anchors.margins: -4096
|
||||
visible: window.visible
|
||||
color: "#7f7f7f7f";
|
||||
radius: 3;
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
anchors.margins: -4096
|
||||
visible: window.visible
|
||||
color: "#7f7f7f7f";
|
||||
radius: 3;
|
||||
}
|
||||
|
||||
Text {
|
||||
y: -implicitHeight - iconSize / 2
|
||||
text: window.title
|
||||
elide: Text.ElideRight
|
||||
font.bold: true
|
||||
color: window.focus ? "white" : "gray"
|
||||
style: Text.Outline;
|
||||
styleColor: "black"
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
y: -implicitHeight - iconSize / 2
|
||||
text: window.title
|
||||
elide: Text.ElideRight
|
||||
font.bold: true
|
||||
color: window.focus ? "white" : "gray"
|
||||
style: Text.Outline;
|
||||
styleColor: "black"
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -250,6 +250,11 @@ Menu::Menu() {
|
|||
// View > Mini Mirror
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::MiniMirror, 0, false);
|
||||
|
||||
// View > Center Player In View
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::CenterPlayerInView,
|
||||
0, true, qApp, SLOT(rotationModeChanged()),
|
||||
UNSPECIFIED_POSITION, "Advanced");
|
||||
|
||||
|
||||
// Navigate menu ----------------------------------
|
||||
MenuWrapper* navigateMenu = addMenu("Navigate");
|
||||
|
@ -636,11 +641,6 @@ Menu::Menu() {
|
|||
|
||||
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true,
|
||||
NULL, NULL, UNSPECIFIED_POSITION, "Advanced");
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::CenterPlayerInView,
|
||||
0, false, qApp, SLOT(rotationModeChanged()),
|
||||
UNSPECIFIED_POSITION, "Advanced");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -56,14 +56,15 @@
|
|||
using namespace std;
|
||||
|
||||
const glm::vec3 DEFAULT_UP_DIRECTION(0.0f, 1.0f, 0.0f);
|
||||
const float YAW_SPEED = 150.0f; // degrees/sec
|
||||
const float PITCH_SPEED = 100.0f; // degrees/sec
|
||||
const float DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES = 30.0f;
|
||||
|
||||
const float MAX_WALKING_SPEED = 2.5f; // human walking speed
|
||||
const float MAX_BOOST_SPEED = 0.5f * MAX_WALKING_SPEED; // keyboard motor gets additive boost below this speed
|
||||
const float MIN_AVATAR_SPEED = 0.05f; // speed is set to zero below this
|
||||
|
||||
const float YAW_SPEED_DEFAULT = 120.0f; // degrees/sec
|
||||
const float PITCH_SPEED_DEFAULT = 90.0f; // degrees/sec
|
||||
|
||||
// TODO: normalize avatar speed for standard avatar size, then scale all motion logic
|
||||
// to properly follow avatar size.
|
||||
float MAX_AVATAR_SPEED = 30.0f;
|
||||
|
@ -86,6 +87,8 @@ MyAvatar::MyAvatar(RigPointer rig) :
|
|||
_isPushing(false),
|
||||
_isBraking(false),
|
||||
_boomLength(ZOOM_DEFAULT),
|
||||
_yawSpeed(YAW_SPEED_DEFAULT),
|
||||
_pitchSpeed(PITCH_SPEED_DEFAULT),
|
||||
_thrust(0.0f),
|
||||
_keyboardMotorVelocity(0.0f),
|
||||
_keyboardMotorTimescale(DEFAULT_KEYBOARD_MOTOR_TIMESCALE),
|
||||
|
@ -1324,7 +1327,7 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
|||
|
||||
void MyAvatar::updateOrientation(float deltaTime) {
|
||||
// Smoothly rotate body with arrow keys
|
||||
float targetSpeed = _driveKeys[YAW] * YAW_SPEED;
|
||||
float targetSpeed = _driveKeys[YAW] * _yawSpeed;
|
||||
if (targetSpeed != 0.0f) {
|
||||
const float ROTATION_RAMP_TIMESCALE = 0.1f;
|
||||
float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
|
||||
|
@ -1360,7 +1363,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
// update body orientation by movement inputs
|
||||
setOrientation(getOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f))));
|
||||
|
||||
getHead()->setBasePitch(getHead()->getBasePitch() + _driveKeys[PITCH] * PITCH_SPEED * deltaTime);
|
||||
getHead()->setBasePitch(getHead()->getBasePitch() + _driveKeys[PITCH] * _pitchSpeed * deltaTime);
|
||||
|
||||
if (qApp->getAvatarUpdater()->isHMDMode()) {
|
||||
glm::quat orientation = glm::quat_cast(getSensorToWorldMatrix()) * getHMDSensorOrientation();
|
||||
|
|
|
@ -110,10 +110,11 @@ public:
|
|||
// This is so the correct camera can be used for rendering.
|
||||
void updateSensorToWorldMatrix();
|
||||
|
||||
void setLeanScale(float scale) { _leanScale = scale; }
|
||||
void setRealWorldFieldOfView(float realWorldFov) { _realWorldFieldOfView.set(realWorldFov); }
|
||||
|
||||
void setLeanScale(float scale) { _leanScale = scale; }
|
||||
float getLeanScale() const { return _leanScale; }
|
||||
|
||||
Q_INVOKABLE glm::vec3 getDefaultEyePosition() const;
|
||||
|
||||
float getRealWorldFieldOfView() { return _realWorldFieldOfView.get(); }
|
||||
|
@ -219,6 +220,12 @@ public:
|
|||
float getBoomLength() const { return _boomLength; }
|
||||
void setBoomLength(float boomLength) { _boomLength = boomLength; }
|
||||
|
||||
float getPitchSpeed() const { return _pitchSpeed; }
|
||||
void setPitchSpeed(float speed) { _pitchSpeed = speed; }
|
||||
|
||||
float getYawSpeed() const { return _yawSpeed; }
|
||||
void setYawSpeed(float speed) { _yawSpeed = speed; }
|
||||
|
||||
static const float ZOOM_MIN;
|
||||
static const float ZOOM_MAX;
|
||||
static const float ZOOM_DEFAULT;
|
||||
|
@ -323,6 +330,8 @@ private:
|
|||
bool _isBraking;
|
||||
|
||||
float _boomLength;
|
||||
float _yawSpeed; // degrees/sec
|
||||
float _pitchSpeed; // degrees/sec
|
||||
|
||||
glm::vec3 _thrust; // impulse accumulator for outside sources
|
||||
|
||||
|
|
|
@ -191,6 +191,24 @@ void setupPreferences() {
|
|||
preferences->addPreference(preference);
|
||||
}
|
||||
|
||||
static const QString AVATAR_CAMERA { "Avatar Camera" };
|
||||
{
|
||||
auto getter = [=]()->float { return myAvatar->getPitchSpeed(); };
|
||||
auto setter = [=](float value) { myAvatar->setPitchSpeed(value); };
|
||||
auto preference = new SpinnerPreference(AVATAR_CAMERA, "Camera Pitch Speed (degrees/second)", getter, setter);
|
||||
preference->setMin(1.0f);
|
||||
preference->setMax(360.0f);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [=]()->float { return myAvatar->getYawSpeed(); };
|
||||
auto setter = [=](float value) { myAvatar->setYawSpeed(value); };
|
||||
auto preference = new SpinnerPreference(AVATAR_CAMERA, "Camera Yaw Speed (degrees/second)", getter, setter);
|
||||
preference->setMin(1.0f);
|
||||
preference->setMax(360.0f);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
|
||||
static const QString AUDIO("Audio");
|
||||
{
|
||||
auto getter = []()->bool {return DependencyManager::get<AudioClient>()->getReceivedAudioStream().getDynamicJitterBuffers(); };
|
||||
|
|
|
@ -351,8 +351,12 @@ float OpenGLDisplayPlugin::presentRate() {
|
|||
}
|
||||
|
||||
void OpenGLDisplayPlugin::drawUnitQuad() {
|
||||
_program->Bind();
|
||||
_plane->Draw();
|
||||
try {
|
||||
_program->Bind();
|
||||
_plane->Draw();
|
||||
} catch (const oglplus::Error& error) {
|
||||
qWarning() << "The present thread encountered an error writing the scene texture to the output: " << error.what();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::enableVsync(bool enable) {
|
||||
|
|
|
@ -29,7 +29,7 @@ EntityScriptingInterface::EntityScriptingInterface() :
|
|||
_entityTree(NULL)
|
||||
{
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
connect(nodeList.data(), &NodeList::canAdjustLocksChanged, this, &EntityScriptingInterface::canAdjustLocksChanged);
|
||||
connect(nodeList.data(), &NodeList::isAllowedEditorChanged, this, &EntityScriptingInterface::canAdjustLocksChanged);
|
||||
connect(nodeList.data(), &NodeList::canRezChanged, this, &EntityScriptingInterface::canRezChanged);
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
|
|||
|
||||
bool EntityScriptingInterface::canAdjustLocks() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
return nodeList->getThisNodeCanAdjustLocks();
|
||||
return nodeList->isAllowedEditor();
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::canRez() {
|
||||
|
|
|
@ -124,10 +124,10 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
|
|||
QUuid senderID;
|
||||
if (senderNode.isNull()) {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
allowLockChange = nodeList->getThisNodeCanAdjustLocks();
|
||||
allowLockChange = nodeList->isAllowedEditor();
|
||||
senderID = nodeList->getSessionUUID();
|
||||
} else {
|
||||
allowLockChange = senderNode->getCanAdjustLocks();
|
||||
allowLockChange = senderNode->isAllowedEditor();
|
||||
senderID = senderNode->getUUID();
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short
|
|||
_numCollectedPackets(0),
|
||||
_numCollectedBytes(0),
|
||||
_packetStatTimer(),
|
||||
_thisNodeCanAdjustLocks(false),
|
||||
_thisNodeCanRez(true)
|
||||
{
|
||||
static bool firstCall = true;
|
||||
|
@ -131,10 +130,10 @@ void LimitedNodeList::setSessionUUID(const QUuid& sessionUUID) {
|
|||
}
|
||||
}
|
||||
|
||||
void LimitedNodeList::setThisNodeCanAdjustLocks(bool canAdjustLocks) {
|
||||
if (_thisNodeCanAdjustLocks != canAdjustLocks) {
|
||||
_thisNodeCanAdjustLocks = canAdjustLocks;
|
||||
emit canAdjustLocksChanged(canAdjustLocks);
|
||||
void LimitedNodeList::setIsAllowedEditor(bool isAllowedEditor) {
|
||||
if (_isAllowedEditor != isAllowedEditor) {
|
||||
_isAllowedEditor = isAllowedEditor;
|
||||
emit isAllowedEditorChanged(isAllowedEditor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -515,7 +514,7 @@ void LimitedNodeList::handleNodeKill(const SharedNodePointer& node) {
|
|||
|
||||
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
||||
bool canAdjustLocks, bool canRez,
|
||||
bool isAllowedEditor, bool canRez,
|
||||
const QUuid& connectionSecret) {
|
||||
NodeHash::const_iterator it = _nodeHash.find(uuid);
|
||||
|
||||
|
@ -524,14 +523,14 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
|
|||
|
||||
matchingNode->setPublicSocket(publicSocket);
|
||||
matchingNode->setLocalSocket(localSocket);
|
||||
matchingNode->setCanAdjustLocks(canAdjustLocks);
|
||||
matchingNode->setIsAllowedEditor(isAllowedEditor);
|
||||
matchingNode->setCanRez(canRez);
|
||||
matchingNode->setConnectionSecret(connectionSecret);
|
||||
|
||||
return matchingNode;
|
||||
} else {
|
||||
// we didn't have this node, so add them
|
||||
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket, canAdjustLocks, canRez, connectionSecret, this);
|
||||
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket, isAllowedEditor, canRez, connectionSecret, this);
|
||||
|
||||
if (nodeType == NodeType::AudioMixer) {
|
||||
LimitedNodeList::flagTimeForConnectionStep(LimitedNodeList::AddedAudioMixer);
|
||||
|
|
|
@ -104,8 +104,8 @@ public:
|
|||
const QUuid& getSessionUUID() const { return _sessionUUID; }
|
||||
void setSessionUUID(const QUuid& sessionUUID);
|
||||
|
||||
bool getThisNodeCanAdjustLocks() const { return _thisNodeCanAdjustLocks; }
|
||||
void setThisNodeCanAdjustLocks(bool canAdjustLocks);
|
||||
bool isAllowedEditor() const { return _isAllowedEditor; }
|
||||
void setIsAllowedEditor(bool isAllowedEditor);
|
||||
|
||||
bool getThisNodeCanRez() const { return _thisNodeCanRez; }
|
||||
void setThisNodeCanRez(bool canRez);
|
||||
|
@ -137,7 +137,7 @@ public:
|
|||
|
||||
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
||||
bool canAdjustLocks = false, bool canRez = false,
|
||||
bool isAllowedEditor = false, bool canRez = false,
|
||||
const QUuid& connectionSecret = QUuid());
|
||||
|
||||
bool hasCompletedInitialSTUN() const { return _hasCompletedInitialSTUN; }
|
||||
|
@ -244,7 +244,7 @@ signals:
|
|||
void localSockAddrChanged(const HifiSockAddr& localSockAddr);
|
||||
void publicSockAddrChanged(const HifiSockAddr& publicSockAddr);
|
||||
|
||||
void canAdjustLocksChanged(bool canAdjustLocks);
|
||||
void isAllowedEditorChanged(bool isAllowedEditor);
|
||||
void canRezChanged(bool canRez);
|
||||
|
||||
protected:
|
||||
|
@ -289,7 +289,7 @@ protected:
|
|||
int _numCollectedBytes;
|
||||
|
||||
QElapsedTimer _packetStatTimer;
|
||||
bool _thisNodeCanAdjustLocks;
|
||||
bool _isAllowedEditor { false };
|
||||
bool _thisNodeCanRez;
|
||||
|
||||
QPointer<QTimer> _initialSTUNTimer;
|
||||
|
|
|
@ -47,7 +47,7 @@ const QString& NodeType::getNodeTypeName(NodeType_t nodeType) {
|
|||
}
|
||||
|
||||
Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
||||
const HifiSockAddr& localSocket, bool canAdjustLocks, bool canRez, const QUuid& connectionSecret,
|
||||
const HifiSockAddr& localSocket, bool isAllowedEditor, bool canRez, const QUuid& connectionSecret,
|
||||
QObject* parent) :
|
||||
NetworkPeer(uuid, publicSocket, localSocket, parent),
|
||||
_type(type),
|
||||
|
@ -57,7 +57,7 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
|||
_clockSkewUsec(0),
|
||||
_mutex(),
|
||||
_clockSkewMovingPercentile(30, 0.8f), // moving 80th percentile of 30 samples
|
||||
_canAdjustLocks(canAdjustLocks),
|
||||
_isAllowedEditor(isAllowedEditor),
|
||||
_canRez(canRez)
|
||||
{
|
||||
// Update socket's object name
|
||||
|
@ -84,7 +84,7 @@ QDataStream& operator<<(QDataStream& out, const Node& node) {
|
|||
out << node._uuid;
|
||||
out << node._publicSocket;
|
||||
out << node._localSocket;
|
||||
out << node._canAdjustLocks;
|
||||
out << node._isAllowedEditor;
|
||||
out << node._canRez;
|
||||
|
||||
return out;
|
||||
|
@ -95,7 +95,7 @@ QDataStream& operator>>(QDataStream& in, Node& node) {
|
|||
in >> node._uuid;
|
||||
in >> node._publicSocket;
|
||||
in >> node._localSocket;
|
||||
in >> node._canAdjustLocks;
|
||||
in >> node._isAllowedEditor;
|
||||
in >> node._canRez;
|
||||
|
||||
return in;
|
||||
|
|
|
@ -33,7 +33,7 @@ class Node : public NetworkPeer {
|
|||
public:
|
||||
Node(const QUuid& uuid, NodeType_t type,
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
||||
bool canAdjustLocks, bool canRez, const QUuid& connectionSecret = QUuid(),
|
||||
bool isAllowedEditor, bool canRez, const QUuid& connectionSecret = QUuid(),
|
||||
QObject* parent = 0);
|
||||
|
||||
bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; }
|
||||
|
@ -58,8 +58,8 @@ public:
|
|||
void updateClockSkewUsec(int clockSkewSample);
|
||||
QMutex& getMutex() { return _mutex; }
|
||||
|
||||
void setCanAdjustLocks(bool canAdjustLocks) { _canAdjustLocks = canAdjustLocks; }
|
||||
bool getCanAdjustLocks() { return _canAdjustLocks; }
|
||||
void setIsAllowedEditor(bool isAllowedEditor) { _isAllowedEditor = isAllowedEditor; }
|
||||
bool isAllowedEditor() { return _isAllowedEditor; }
|
||||
|
||||
void setCanRez(bool canRez) { _canRez = canRez; }
|
||||
bool getCanRez() { return _canRez; }
|
||||
|
@ -81,7 +81,7 @@ private:
|
|||
int _clockSkewUsec;
|
||||
QMutex _mutex;
|
||||
MovingPercentile _clockSkewMovingPercentile;
|
||||
bool _canAdjustLocks;
|
||||
bool _isAllowedEditor;
|
||||
bool _canRez;
|
||||
};
|
||||
|
||||
|
|
|
@ -512,9 +512,9 @@ void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message)
|
|||
packetStream >> newUUID;
|
||||
setSessionUUID(newUUID);
|
||||
|
||||
quint8 thisNodeCanAdjustLocks;
|
||||
packetStream >> thisNodeCanAdjustLocks;
|
||||
setThisNodeCanAdjustLocks((bool) thisNodeCanAdjustLocks);
|
||||
quint8 isAllowedEditor;
|
||||
packetStream >> isAllowedEditor;
|
||||
setIsAllowedEditor((bool) isAllowedEditor);
|
||||
|
||||
quint8 thisNodeCanRez;
|
||||
packetStream >> thisNodeCanRez;
|
||||
|
@ -546,10 +546,10 @@ void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) {
|
|||
qint8 nodeType;
|
||||
QUuid nodeUUID, connectionUUID;
|
||||
HifiSockAddr nodePublicSocket, nodeLocalSocket;
|
||||
bool canAdjustLocks;
|
||||
bool isAllowedEditor;
|
||||
bool canRez;
|
||||
|
||||
packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> canAdjustLocks >> canRez;
|
||||
packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> isAllowedEditor >> canRez;
|
||||
|
||||
// if the public socket address is 0 then it's reachable at the same IP
|
||||
// as the domain server
|
||||
|
@ -560,7 +560,7 @@ void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) {
|
|||
packetStream >> connectionUUID;
|
||||
|
||||
SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket,
|
||||
nodeLocalSocket, canAdjustLocks, canRez,
|
||||
nodeLocalSocket, isAllowedEditor, canRez,
|
||||
connectionUUID);
|
||||
}
|
||||
|
||||
|
|
|
@ -278,7 +278,7 @@
|
|||
modelURL: modelURL,
|
||||
position: position,
|
||||
restitution: 0,
|
||||
damping:0.5,
|
||||
damping: 0.5,
|
||||
collisionSoundURL: "http://hifi-content.s3.amazonaws.com/james/pistol/sounds/drop.wav",
|
||||
dimensions: {
|
||||
x: 0.05,
|
||||
|
@ -300,18 +300,29 @@
|
|||
dynamic: true,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
spatialKey: {
|
||||
rightRelativePosition: {
|
||||
x: 0.03,
|
||||
y: 0.0,
|
||||
z: -0.065
|
||||
},
|
||||
leftRelativePosition: {
|
||||
x: -0.03,
|
||||
y: 0.00,
|
||||
z: -0.065
|
||||
},
|
||||
relativeRotation: Quat.fromPitchYawRollDegrees(90, 90, 0)
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.07079616189002991,
|
||||
y: 0.20177987217903137,
|
||||
z: 0.06374628841876984
|
||||
}, {
|
||||
x: -0.5863648653030396,
|
||||
y: -0.46007341146469116,
|
||||
z: 0.46949487924575806,
|
||||
w: -0.4733745753765106
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: 0.1802254319190979,
|
||||
y: 0.13442856073379517,
|
||||
z: 0.08504903316497803
|
||||
}, {
|
||||
x: 0.2198076844215393,
|
||||
y: -0.7377811074256897,
|
||||
z: 0.2780133783817291,
|
||||
w: 0.574519157409668
|
||||
}]
|
||||
}
|
||||
},
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
|
@ -334,7 +345,7 @@
|
|||
var BOW_ROTATION = Quat.fromPitchYawRollDegrees(-103.05, -178.60, -87.27);
|
||||
var MODEL_URL = "https://hifi-public.s3.amazonaws.com/models/bow/new/bow-deadly.fbx";
|
||||
var COLLISION_HULL_URL = "https://hifi-public.s3.amazonaws.com/models/bow/new/bow_collision_hull.obj";
|
||||
|
||||
|
||||
var BOW_DIMENSIONS = {
|
||||
x: 0.04,
|
||||
y: 1.3,
|
||||
|
@ -378,19 +389,30 @@
|
|||
resetMe: true
|
||||
},
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true,
|
||||
spatialKey: {
|
||||
rightRelativePosition: {
|
||||
x: 0.03,
|
||||
y: 0.08,
|
||||
z: 0.11
|
||||
},
|
||||
leftRelativePosition: {
|
||||
x: -0.03,
|
||||
y: 0.08,
|
||||
z: 0.11
|
||||
},
|
||||
relativeRotation: Quat.fromPitchYawRollDegrees(180, 90, 90)
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.03960523009300232,
|
||||
y: 0.01979270577430725,
|
||||
z: 0.03294898942112923
|
||||
}, {
|
||||
x: -0.7257906794548035,
|
||||
y: -0.4611682891845703,
|
||||
z: 0.4436084032058716,
|
||||
w: -0.25251442193984985
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: 0.0055799782276153564,
|
||||
y: 0.04354757443070412,
|
||||
z: 0.05119767785072327
|
||||
}, {
|
||||
x: -0.14914104342460632,
|
||||
y: 0.6448180079460144,
|
||||
z: -0.2888556718826294,
|
||||
w: -0.6917579770088196
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -455,6 +477,7 @@
|
|||
|
||||
makeBow();
|
||||
}
|
||||
|
||||
function createFire() {
|
||||
|
||||
|
||||
|
@ -860,6 +883,30 @@
|
|||
},
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.0717092975974083,
|
||||
y: 0.1166968047618866,
|
||||
z: 0.07085515558719635
|
||||
}, {
|
||||
x: -0.7195770740509033,
|
||||
y: 0.175227552652359,
|
||||
z: 0.5953742265701294,
|
||||
w: 0.31150275468826294
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: 0.0806504637002945,
|
||||
y: 0.09710478782653809,
|
||||
z: 0.08610185235738754
|
||||
}, {
|
||||
x: 0.5630447864532471,
|
||||
y: -0.2545935809612274,
|
||||
z: 0.7855332493782043,
|
||||
w: 0.033170729875564575
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
@ -1231,22 +1278,32 @@
|
|||
resetMe: true
|
||||
},
|
||||
grabbableKey: {
|
||||
spatialKey: {
|
||||
rightRelativePosition: {
|
||||
x: -0.05,
|
||||
y: .06,
|
||||
z: 0.05
|
||||
},
|
||||
leftRelativePosition: {
|
||||
x: 0.05,
|
||||
y: 0.06,
|
||||
z: 0.05
|
||||
},
|
||||
relativeRotation: Quat.fromPitchYawRollDegrees(0, -90, -90)
|
||||
},
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.1177130937576294,
|
||||
y: 0.12922893464565277,
|
||||
z: 0.08307232707738876
|
||||
}, {
|
||||
x: 0.4934672713279724,
|
||||
y: 0.3605862259864807,
|
||||
z: 0.6394805908203125,
|
||||
w: -0.4664038419723511
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: 0.09151676297187805,
|
||||
y: 0.13639454543590546,
|
||||
z: 0.09354984760284424
|
||||
}, {
|
||||
x: -0.19628101587295532,
|
||||
y: 0.6418180465698242,
|
||||
z: 0.2830369472503662,
|
||||
w: 0.6851521730422974
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -1280,14 +1337,30 @@
|
|||
resetMe: true
|
||||
},
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true,
|
||||
spatialKey: {
|
||||
relativePosition: {
|
||||
x: 0,
|
||||
y: 0.1,
|
||||
z: 0
|
||||
},
|
||||
relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 90)
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
"wearable": {
|
||||
"joints": {
|
||||
"RightHand": [{
|
||||
"x": 0.11421211808919907,
|
||||
"y": 0.06508062779903412,
|
||||
"z": 0.06317152827978134
|
||||
}, {
|
||||
"x": -0.7886992692947388,
|
||||
"y": -0.6108893156051636,
|
||||
"z": -0.05003821849822998,
|
||||
"w": 0.047579944133758545
|
||||
}],
|
||||
"LeftHand": [{
|
||||
"x": 0.03530977666378021,
|
||||
"y": 0.11278322339057922,
|
||||
"z": 0.049768272787332535
|
||||
}, {
|
||||
"x": -0.050609711557626724,
|
||||
"y": -0.11595471203327179,
|
||||
"z": 0.3554558753967285,
|
||||
"w": 0.9260908961296082
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -1595,4 +1668,4 @@
|
|||
};
|
||||
// entity scripts always need to return a newly constructed object of our type
|
||||
return new ResetSwitch();
|
||||
});
|
||||
});
|
|
@ -284,18 +284,29 @@ MasterReset = function() {
|
|||
collisionSoundURL: "http://hifi-content.s3.amazonaws.com/james/pistol/sounds/drop.wav",
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
spatialKey: {
|
||||
rightRelativePosition: {
|
||||
x: 0.03,
|
||||
y: 0.0,
|
||||
z: -0.065
|
||||
},
|
||||
leftRelativePosition: {
|
||||
x: -0.03,
|
||||
y: 0.00,
|
||||
z: -0.065
|
||||
},
|
||||
relativeRotation: Quat.fromPitchYawRollDegrees(90, 90, 0)
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.07079616189002991,
|
||||
y: 0.20177987217903137,
|
||||
z: 0.06374628841876984
|
||||
}, {
|
||||
x: -0.5863648653030396,
|
||||
y: -0.46007341146469116,
|
||||
z: 0.46949487924575806,
|
||||
w: -0.4733745753765106
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: 0.1802254319190979,
|
||||
y: 0.13442856073379517,
|
||||
z: 0.08504903316497803
|
||||
}, {
|
||||
x: 0.2198076844215393,
|
||||
y: -0.7377811074256897,
|
||||
z: 0.2780133783817291,
|
||||
w: 0.574519157409668
|
||||
}]
|
||||
}
|
||||
},
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
|
@ -318,7 +329,7 @@ MasterReset = function() {
|
|||
var BOW_ROTATION = Quat.fromPitchYawRollDegrees(-103.05, -178.60, -87.27);
|
||||
var MODEL_URL = "https://hifi-public.s3.amazonaws.com/models/bow/new/bow-deadly.fbx";
|
||||
var COLLISION_HULL_URL = "https://hifi-public.s3.amazonaws.com/models/bow/new/bow_collision_hull.obj";
|
||||
|
||||
|
||||
var BOW_DIMENSIONS = {
|
||||
x: 0.04,
|
||||
y: 1.3,
|
||||
|
@ -362,19 +373,30 @@ MasterReset = function() {
|
|||
resetMe: true
|
||||
},
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true,
|
||||
spatialKey: {
|
||||
rightRelativePosition: {
|
||||
x: 0.03,
|
||||
y: 0.08,
|
||||
z: 0.11
|
||||
},
|
||||
leftRelativePosition: {
|
||||
x: -0.03,
|
||||
y: 0.08,
|
||||
z: 0.11
|
||||
},
|
||||
relativeRotation: Quat.fromPitchYawRollDegrees(180, 90, 90)
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.03960523009300232,
|
||||
y: 0.01979270577430725,
|
||||
z: 0.03294898942112923
|
||||
}, {
|
||||
x: -0.7257906794548035,
|
||||
y: -0.4611682891845703,
|
||||
z: 0.4436084032058716,
|
||||
w: -0.25251442193984985
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: 0.0055799782276153564,
|
||||
y: 0.04354757443070412,
|
||||
z: 0.05119767785072327
|
||||
}, {
|
||||
x: -0.14914104342460632,
|
||||
y: 0.6448180079460144,
|
||||
z: -0.2888556718826294,
|
||||
w: -0.6917579770088196
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -848,6 +870,30 @@ MasterReset = function() {
|
|||
},
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.0717092975974083,
|
||||
y: 0.1166968047618866,
|
||||
z: 0.07085515558719635
|
||||
}, {
|
||||
x: -0.7195770740509033,
|
||||
y: 0.175227552652359,
|
||||
z: 0.5953742265701294,
|
||||
w: 0.31150275468826294
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: 0.0806504637002945,
|
||||
y: 0.09710478782653809,
|
||||
z: 0.08610185235738754
|
||||
}, {
|
||||
x: 0.5630447864532471,
|
||||
y: -0.2545935809612274,
|
||||
z: 0.7855332493782043,
|
||||
w: 0.033170729875564575
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
@ -1140,7 +1186,7 @@ MasterReset = function() {
|
|||
var dice2 = Entities.addEntity(diceProps);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function createGates() {
|
||||
var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/ryan/fence.fbx';
|
||||
|
||||
|
@ -1219,22 +1265,32 @@ MasterReset = function() {
|
|||
resetMe: true
|
||||
},
|
||||
grabbableKey: {
|
||||
spatialKey: {
|
||||
rightRelativePosition: {
|
||||
x: -0.05,
|
||||
y: .06,
|
||||
z: 0.05
|
||||
},
|
||||
leftRelativePosition: {
|
||||
x: 0.05,
|
||||
y: 0.06,
|
||||
z: 0.05
|
||||
},
|
||||
relativeRotation: Quat.fromPitchYawRollDegrees(0, -90, -90)
|
||||
},
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.1177130937576294,
|
||||
y: 0.12922893464565277,
|
||||
z: 0.08307232707738876
|
||||
}, {
|
||||
x: 0.4934672713279724,
|
||||
y: 0.3605862259864807,
|
||||
z: 0.6394805908203125,
|
||||
w: -0.4664038419723511
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: 0.09151676297187805,
|
||||
y: 0.13639454543590546,
|
||||
z: 0.09354984760284424
|
||||
}, {
|
||||
x: -0.19628101587295532,
|
||||
y: 0.6418180465698242,
|
||||
z: 0.2830369472503662,
|
||||
w: 0.6851521730422974
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -1268,14 +1324,30 @@ MasterReset = function() {
|
|||
resetMe: true
|
||||
},
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true,
|
||||
spatialKey: {
|
||||
relativePosition: {
|
||||
x: 0,
|
||||
y: 0.1,
|
||||
z: 0
|
||||
},
|
||||
relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 90)
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
"wearable": {
|
||||
"joints": {
|
||||
"RightHand": [{
|
||||
"x": 0.11421211808919907,
|
||||
"y": 0.06508062779903412,
|
||||
"z": 0.06317152827978134
|
||||
}, {
|
||||
"x": -0.7886992692947388,
|
||||
"y": -0.6108893156051636,
|
||||
"z": -0.05003821849822998,
|
||||
"w": 0.047579944133758545
|
||||
}],
|
||||
"LeftHand": [{
|
||||
"x": 0.03530977666378021,
|
||||
"y": 0.11278322339057922,
|
||||
"z": 0.049768272787332535
|
||||
}, {
|
||||
"x": -0.050609711557626724,
|
||||
"y": -0.11595471203327179,
|
||||
"z": 0.3554558753967285,
|
||||
"w": 0.9260908961296082
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -1578,4 +1650,4 @@ MasterReset = function() {
|
|||
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
}
|
||||
};
|
||||
};
|
Loading…
Reference in a new issue