mirror of
https://github.com/lubosz/overte.git
synced 2025-04-19 17:03:43 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into poseFilters
This commit is contained in:
commit
d7fb3367c1
48 changed files with 1112 additions and 286 deletions
|
@ -29,8 +29,8 @@
|
|||
#include <udt/PacketHeaders.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <ScriptCache.h>
|
||||
#include <SoundCache.h>
|
||||
#include <ScriptEngines.h>
|
||||
#include <SoundCache.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include <recording/Deck.h>
|
||||
|
|
|
@ -325,7 +325,7 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) {
|
|||
_stats.overBudgetAvatars++;
|
||||
detail = PALIsOpen ? AvatarData::PALMinimum : AvatarData::NoData;
|
||||
} else if (!isInView) {
|
||||
detail = PALIsOpen ? AvatarData::PALMinimum : AvatarData::NoData;
|
||||
detail = PALIsOpen ? AvatarData::PALMinimum : AvatarData::MinimumData;
|
||||
nodeData->incrementAvatarOutOfView();
|
||||
} else {
|
||||
detail = distribution(generator) < AVATAR_SEND_FULL_UPDATE_RATIO
|
||||
|
|
BIN
interface/resources/icons/loadingDark.gif
Normal file
BIN
interface/resources/icons/loadingDark.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
BIN
interface/resources/meshes/Jointy3/Jointy3.fbx
Normal file
BIN
interface/resources/meshes/Jointy3/Jointy3.fbx
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 2.6 MiB |
Binary file not shown.
Before Width: | Height: | Size: 2.9 MiB |
Binary file not shown.
Before Width: | Height: | Size: 645 KiB |
|
@ -1,135 +1,85 @@
|
|||
name = being_of_light
|
||||
name = Jointy3
|
||||
type = body+head
|
||||
scale = 1
|
||||
filename = being_of_light/being_of_light.fbx
|
||||
texdir = being_of_light/textures
|
||||
joint = jointRoot = Hips
|
||||
filename = Jointy3/Jointy3.fbx
|
||||
texdir = Jointy3/textures
|
||||
joint = jointNeck = Neck
|
||||
joint = jointLeftHand = LeftHand
|
||||
joint = jointHead = HeadTop_End
|
||||
joint = jointEyeRight = RightEye
|
||||
joint = jointHead = Head
|
||||
joint = jointRightHand = RightHand
|
||||
joint = jointRoot = Hips
|
||||
joint = jointLean = Spine
|
||||
joint = jointEyeLeft = LeftEye
|
||||
joint = jointRightHand = RightHand
|
||||
joint = jointNeck = Head
|
||||
joint = jointEyeRight = RightEye
|
||||
freeJoint = LeftArm
|
||||
freeJoint = LeftForeArm
|
||||
freeJoint = RightArm
|
||||
freeJoint = RightForeArm
|
||||
bs = MouthFrown_L = Frown_Left = 1
|
||||
bs = MouthLeft = Midmouth_Left = 1
|
||||
bs = BrowsU_R = BrowsUp_Right = 1
|
||||
bs = ChinUpperRaise = UpperLipUp_Right = 0.5
|
||||
bs = ChinUpperRaise = UpperLipUp_Left = 0.5
|
||||
bs = MouthSmile_R = Smile_Right = 1
|
||||
bs = MouthDimple_L = Smile_Left = 0.25
|
||||
bs = EyeBlink_L = Blink_Left = 1
|
||||
bs = BrowsD_L = BrowsDown_Left = 1
|
||||
bs = MouthFrown_R = Frown_Right = 1
|
||||
bs = MouthDimple_R = Smile_Right = 0.25
|
||||
bs = Sneer = Squint_Right = 0.5
|
||||
bs = Sneer = Squint_Left = 0.5
|
||||
bs = Sneer = NoseScrunch_Right = 0.75
|
||||
bs = Sneer = NoseScrunch_Left = 0.75
|
||||
bs = EyeSquint_L = Squint_Left = 1
|
||||
bs = EyeBlink_R = Blink_Right = 1
|
||||
bs = JawLeft = JawRotateY_Left = 0.5
|
||||
bs = BrowsD_R = BrowsDown_Right = 1
|
||||
bs = EyeSquint_R = Squint_Right = 1
|
||||
bs = Puff = CheekPuff_Right = 1
|
||||
bs = Puff = CheekPuff_Left = 1
|
||||
bs = LipsUpperClose = UpperLipIn = 1
|
||||
bs = JawOpen = MouthOpen = 0.69999999999999996
|
||||
bs = LipsUpperUp = UpperLipUp_Right = 0.69999999999999996
|
||||
bs = LipsUpperUp = UpperLipUp_Left = 0.69999999999999996
|
||||
bs = LipsLowerDown = LowerLipDown_Right = 0.69999999999999996
|
||||
bs = LipsLowerDown = LowerLipDown_Left = 0.69999999999999996
|
||||
bs = LipsLowerOpen = LowerLipOut = 1
|
||||
bs = EyeOpen_L = EyesWide_Left = 1
|
||||
bs = LipsPucker = MouthNarrow_Right = 1
|
||||
bs = LipsPucker = MouthNarrow_Left = 1
|
||||
bs = EyeOpen_R = EyesWide_Right = 1
|
||||
bs = JawRight = Jaw_Right = 1
|
||||
bs = MouthRight = Midmouth_Right = 1
|
||||
bs = ChinLowerRaise = Jaw_Up = 1
|
||||
bs = LipsUpperOpen = UpperLipOut = 1
|
||||
bs = BrowsU_C = BrowsUp_Right = 1
|
||||
bs = BrowsU_C = BrowsUp_Left = 1
|
||||
bs = JawFwd = JawForeward = 1
|
||||
bs = BrowsU_L = BrowsUp_Left = 1
|
||||
bs = MouthSmile_L = Smile_Left = 1
|
||||
bs = LipsLowerClose = LowerLipIn = 1
|
||||
bs = LipsFunnel = TongueUp = 1
|
||||
bs = LipsFunnel = MouthWhistle_NarrowAdjust_Right = 0.5
|
||||
bs = LipsFunnel = MouthWhistle_NarrowAdjust_Left = 0.5
|
||||
bs = LipsFunnel = MouthNarrow_Right = 1
|
||||
bs = LipsFunnel = MouthNarrow_Left = 1
|
||||
bs = LipsFunnel = Jaw_Down = 0.35999999999999999
|
||||
bs = LipsFunnel = JawForeward = 0.39000000000000001
|
||||
jointIndex = LeftHandIndex1 = 50
|
||||
jointIndex = LeftHandIndex2 = 51
|
||||
jointIndex = LeftHandIndex3 = 52
|
||||
jointIndex = LeftHandIndex4 = 53
|
||||
jointIndex = Spine1 = 12
|
||||
jointIndex = Spine2 = 13
|
||||
jointIndex = RightHandThumb1 = 18
|
||||
jointIndex = RightHandThumb2 = 19
|
||||
jointIndex = RightHandThumb3 = 20
|
||||
jointIndex = RightHandThumb4 = 21
|
||||
jointIndex = LeftFoot = 8
|
||||
jointIndex = LeftForeArm = 40
|
||||
jointIndex = Neck = 62
|
||||
jointIndex = Head = 63
|
||||
jointIndex = Hips = 0
|
||||
jointIndex = RightHandPinky1 = 30
|
||||
jointIndex = RightHandPinky2 = 31
|
||||
jointIndex = RightHandPinky3 = 32
|
||||
jointIndex = RightHandPinky4 = 33
|
||||
jointIndex = RightLeg = 2
|
||||
jointIndex = RightForeArm = 16
|
||||
jointIndex = LeftHandRing1 = 46
|
||||
jointIndex = LeftHandRing2 = 47
|
||||
jointIndex = LeftHandRing3 = 48
|
||||
jointIndex = LeftHandRing4 = 49
|
||||
jointIndex = LeftHandThumb1 = 54
|
||||
jointIndex = LeftHandThumb2 = 55
|
||||
jointIndex = LeftHandThumb3 = 56
|
||||
jointIndex = LeftHandThumb4 = 57
|
||||
jointIndex = HeadTop_End = 66
|
||||
jointIndex = LeftUpLeg = 6
|
||||
jointIndex = LeftToeBase = 9
|
||||
jointIndex = LeftHandPinky1 = 42
|
||||
jointIndex = LeftHandPinky2 = 43
|
||||
jointIndex = LeftHandPinky3 = 44
|
||||
jointIndex = LeftHandPinky4 = 45
|
||||
jointIndex = LeftLeg = 7
|
||||
jointIndex = RightEye = 65
|
||||
jointIndex = RightHand = 17
|
||||
jointIndex = RightToeBase = 4
|
||||
jointIndex = RightUpLeg = 1
|
||||
jointIndex = RightArm = 15
|
||||
jointIndex = RightHandRing1 = 26
|
||||
jointIndex = RightHandRing2 = 27
|
||||
jointIndex = RightHandRing3 = 28
|
||||
jointIndex = RightHandRing4 = 29
|
||||
jointIndex = RightHandIndex1 = 22
|
||||
jointIndex = RightHandIndex2 = 23
|
||||
jointIndex = RightHandIndex3 = 24
|
||||
jointIndex = RightHandIndex4 = 25
|
||||
jointIndex = LeftToe_End = 10
|
||||
jointIndex = LeftHandMiddle1 = 58
|
||||
jointIndex = LeftHandMiddle2 = 59
|
||||
jointIndex = LeftHandMiddle3 = 60
|
||||
jointIndex = LeftShoulder = 38
|
||||
jointIndex = LeftHandMiddle4 = 61
|
||||
jointIndex = RightFoot = 3
|
||||
jointIndex = LeftHand = 41
|
||||
jointIndex = RightHandMiddle1 = 34
|
||||
jointIndex = RightHandMiddle2 = 35
|
||||
jointIndex = RightHandMiddle3 = 36
|
||||
jointIndex = LeftHandIndex3 = 56
|
||||
jointIndex = Hips = 0
|
||||
jointIndex = LeftHandRing2 = 47
|
||||
jointIndex = LeftHandThumb3 = 60
|
||||
jointIndex = RightShoulder = 14
|
||||
jointIndex = LeftEye = 64
|
||||
jointIndex = RightHandMiddle4 = 37
|
||||
jointIndex = Body = 67
|
||||
jointIndex = LeftArm = 39
|
||||
jointIndex = RightHandRing1 = 30
|
||||
jointIndex = RightHandRing3 = 32
|
||||
jointIndex = LeftHandPinky4 = 45
|
||||
jointIndex = LeftHandRing1 = 46
|
||||
jointIndex = LeftFoot = 8
|
||||
jointIndex = RightHandIndex2 = 23
|
||||
jointIndex = RightToeBase = 4
|
||||
jointIndex = RightHandMiddle4 = 29
|
||||
jointIndex = RightHandPinky4 = 37
|
||||
jointIndex = LeftToe_End = 10
|
||||
jointIndex = RightEye = 66
|
||||
jointIndex = RightHandPinky2 = 35
|
||||
jointIndex = RightHandRing2 = 31
|
||||
jointIndex = LeftHand = 41
|
||||
jointIndex = RightToe_End = 5
|
||||
jointIndex = LeftEye = 65
|
||||
jointIndex = LeftHandThumb2 = 59
|
||||
jointIndex = pCylinder73Shape1 = 67
|
||||
jointIndex = LeftShoulder = 38
|
||||
jointIndex = LeftHandIndex2 = 55
|
||||
jointIndex = RightForeArm = 16
|
||||
jointIndex = LeftHandMiddle2 = 51
|
||||
jointIndex = RightHandRing4 = 33
|
||||
jointIndex = LeftLeg = 7
|
||||
jointIndex = LeftHandThumb4 = 61
|
||||
jointIndex = LeftForeArm = 40
|
||||
jointIndex = HeadTop_End = 64
|
||||
jointIndex = RightHandPinky1 = 34
|
||||
jointIndex = RightHandIndex1 = 22
|
||||
jointIndex = LeftHandIndex1 = 54
|
||||
jointIndex = RightLeg = 2
|
||||
jointIndex = RightHandIndex4 = 25
|
||||
jointIndex = Neck = 62
|
||||
jointIndex = LeftHandMiddle1 = 50
|
||||
jointIndex = RightHandPinky3 = 36
|
||||
jointIndex = LeftHandPinky2 = 43
|
||||
jointIndex = RightHandMiddle3 = 28
|
||||
jointIndex = RightHandThumb4 = 21
|
||||
jointIndex = LeftUpLeg = 6
|
||||
jointIndex = RightFoot = 3
|
||||
jointIndex = LeftHandThumb1 = 58
|
||||
jointIndex = LeftArm = 39
|
||||
jointIndex = RightHandMiddle1 = 26
|
||||
jointIndex = LeftHandRing3 = 48
|
||||
jointIndex = LeftHandMiddle4 = 53
|
||||
jointIndex = RightUpLeg = 1
|
||||
jointIndex = RightHandMiddle2 = 27
|
||||
jointIndex = LeftToeBase = 9
|
||||
jointIndex = RightHandThumb2 = 19
|
||||
jointIndex = Spine2 = 13
|
||||
jointIndex = Spine = 11
|
||||
jointIndex = LeftHandRing4 = 49
|
||||
jointIndex = Head = 63
|
||||
jointIndex = LeftHandPinky3 = 44
|
||||
jointIndex = LeftHandPinky1 = 42
|
||||
jointIndex = RightHandThumb1 = 18
|
||||
jointIndex = LeftHandIndex4 = 57
|
||||
jointIndex = LeftHandMiddle3 = 52
|
||||
jointIndex = RightHandIndex3 = 24
|
||||
jointIndex = Spine1 = 12
|
||||
jointIndex = RightArm = 15
|
||||
jointIndex = RightHandThumb3 = 20
|
||||
|
|
|
@ -40,7 +40,7 @@ Item {
|
|||
anchors.leftMargin: 8
|
||||
HiFiGlyphs {
|
||||
id: back;
|
||||
enabled: currentPage > 0
|
||||
enabled: currentPage >= 0
|
||||
text: hifi.glyphs.backward
|
||||
color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText
|
||||
size: 48
|
||||
|
@ -107,6 +107,8 @@ Item {
|
|||
function goBack() {
|
||||
if (currentPage > 0) {
|
||||
currentPage--;
|
||||
} else if (parentStackItem) {
|
||||
parentStackItem.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ TabletModalWindow {
|
|||
property var eventBridge;
|
||||
signal sendToScript(var message);
|
||||
property bool isHMD: false
|
||||
|
||||
property bool gotoPreviousApp: false;
|
||||
color: hifi.colors.baseGray
|
||||
|
||||
property int colorScheme: hifi.colorSchemes.dark
|
||||
|
@ -66,8 +66,11 @@ TabletModalWindow {
|
|||
HifiConstants { id: hifi }
|
||||
|
||||
onCanceled: {
|
||||
if (loginDialogRoot.Stack.view !== null) {
|
||||
loginDialogRoot.Stack.view.pop()
|
||||
if (loginDialogRoot.Stack.view) {
|
||||
loginDialogRoot.Stack.view.pop();
|
||||
} else if (gotoPreviousApp) {
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
tablet.returnToPreviousApp();
|
||||
} else {
|
||||
Tablet.getTablet("com.highfidelity.interface.tablet.system").gotoHomeScreen();
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ Item {
|
|||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
enabled: (selected || isMyCard) && activeTab == "nearbyTab";
|
||||
enabled: (selected && activeTab == "nearbyTab") || isMyCard;
|
||||
hoverEnabled: enabled
|
||||
onClicked: {
|
||||
userInfoViewer.url = defaultBaseUrl + "/users/" + userName;
|
||||
|
|
|
@ -1401,6 +1401,13 @@ Rectangle {
|
|||
var selectedIDs = getSelectedConnectionsUserNames();
|
||||
connectionsUserModelData.sort(function (a, b) {
|
||||
var aValue = a[sortProperty].toString().toLowerCase(), bValue = b[sortProperty].toString().toLowerCase();
|
||||
if (!aValue && !bValue) {
|
||||
return 0;
|
||||
} else if (!aValue) {
|
||||
return after;
|
||||
} else if (!bValue) {
|
||||
return before;
|
||||
}
|
||||
switch (true) {
|
||||
case (aValue < bValue): return before;
|
||||
case (aValue > bValue): return after;
|
||||
|
|
|
@ -18,7 +18,7 @@ StackView {
|
|||
initialItem: root
|
||||
objectName: "stack"
|
||||
property string title: "General Settings"
|
||||
|
||||
property alias gotoPreviousApp: root.gotoPreviousApp;
|
||||
property var eventBridge;
|
||||
signal sendToScript(var message);
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ Item {
|
|||
property string subMenu: ""
|
||||
signal showDesktop();
|
||||
property bool shown: true
|
||||
property int currentApp: -1;
|
||||
property alias tabletApps: tabletApps
|
||||
|
||||
function setOption(value) {
|
||||
option = value;
|
||||
|
@ -56,13 +58,48 @@ Item {
|
|||
}
|
||||
|
||||
function loadSource(url) {
|
||||
tabletApps.clear();
|
||||
loader.source = ""; // make sure we load the qml fresh each time.
|
||||
loader.source = url;
|
||||
tabletApps.append({"appUrl": url, "isWebUrl": false, "scriptUrl": "", "appWebUrl": ""});
|
||||
}
|
||||
|
||||
function loadQMLOnTop(url) {
|
||||
tabletApps.append({"appUrl": url, "isWebUrl": false, "scriptUrl": "", "appWebUrl": ""});
|
||||
loader.source = "";
|
||||
loader.source = tabletApps.get(currentApp).appUrl;
|
||||
if (loader.item.hasOwnProperty("gotoPreviousApp")) {
|
||||
loader.item.gotoPreviousApp = true;
|
||||
}
|
||||
}
|
||||
|
||||
function loadWebOnTop(url, injectJavaScriptUrl) {
|
||||
tabletApps.append({"appUrl": loader.source, "isWebUrl": true, "scriptUrl": injectJavaScriptUrl, "appWebUrl": url});
|
||||
loader.item.url = tabletApps.get(currentApp).appWebUrl;
|
||||
loader.item.scriptUrl = tabletApps.get(currentApp).scriptUrl;
|
||||
if (loader.item.hasOwnProperty("gotoPreviousApp")) {
|
||||
loader.item.gotoPreviousApp = true;
|
||||
}
|
||||
}
|
||||
|
||||
function returnToPreviousApp() {
|
||||
tabletApps.remove(currentApp);
|
||||
var isWebPage = tabletApps.get(currentApp).isWebUrl;
|
||||
if (isWebPage) {
|
||||
var webUrl = tabletApps.get(currentApp).appWebUrl;
|
||||
var scriptUrl = tabletApps.get(currentApp).scriptUrl;
|
||||
loadSource("TabletWebView.qml");
|
||||
loadWebUrl(webUrl, scriptUrl);
|
||||
} else {
|
||||
loader.source = tabletApps.get(currentApp).appUrl;
|
||||
}
|
||||
}
|
||||
|
||||
function loadWebUrl(url, injectedJavaScriptUrl) {
|
||||
tabletApps.clear();
|
||||
loader.item.url = url;
|
||||
loader.item.scriptURL = injectedJavaScriptUrl;
|
||||
tabletApps.append({"appUrl": "TabletWebView.qml", "isWebUrl": true, "scriptUrl": injectedJavaScriptUrl, "appWebUrl": url});
|
||||
}
|
||||
|
||||
// used to send a message from qml to interface script.
|
||||
|
@ -97,6 +134,13 @@ Item {
|
|||
username = newUsername;
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: tabletApps
|
||||
onCountChanged: {
|
||||
currentApp = count - 1
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
objectName: "loader"
|
||||
|
|
|
@ -31,6 +31,7 @@ Item {
|
|||
property bool keyboardEnabled: false
|
||||
property bool keyboardRaised: false
|
||||
property bool punctuationMode: false
|
||||
property bool gotoPreviousApp: false
|
||||
|
||||
property var tablet;
|
||||
|
||||
|
@ -55,7 +56,13 @@ Item {
|
|||
}
|
||||
|
||||
function closeDialog() {
|
||||
Tablet.getTablet("com.highfidelity.interface.tablet.system").gotoHomeScreen();
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
|
||||
if (gotoPreviousApp) {
|
||||
tablet.returnToPreviousApp();
|
||||
} else {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
|
|
@ -129,6 +129,7 @@
|
|||
#include "AudioClient.h"
|
||||
#include "audio/AudioScope.h"
|
||||
#include "avatar/AvatarManager.h"
|
||||
#include "avatar/ScriptAvatar.h"
|
||||
#include "CrashHandler.h"
|
||||
#include "devices/DdeFaceTracker.h"
|
||||
#include "devices/EyeTracker.h"
|
||||
|
@ -6416,7 +6417,7 @@ void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRa
|
|||
// If we're not doing an animated snapshot as well...
|
||||
if (!includeAnimated || !(SnapshotAnimated::alsoTakeAnimatedSnapshot.get())) {
|
||||
// Tell the dependency manager that the capture of the still snapshot has taken place.
|
||||
emit DependencyManager::get<WindowScriptingInterface>()->snapshotTaken(path, "", notify);
|
||||
emit DependencyManager::get<WindowScriptingInterface>()->stillSnapshotTaken(path, notify);
|
||||
} else {
|
||||
// Get an animated GIF snapshot and save it
|
||||
SnapshotAnimated::saveSnapshotAnimated(path, aspectRatio, qApp, DependencyManager::get<WindowScriptingInterface>());
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "Avatar.h"
|
||||
#include "AvatarMotionState.h"
|
||||
#include "ScriptAvatar.h"
|
||||
|
||||
class MyAvatar;
|
||||
class AudioInjector;
|
||||
|
@ -41,6 +42,10 @@ public:
|
|||
void init();
|
||||
|
||||
std::shared_ptr<MyAvatar> getMyAvatar() { return _myAvatar; }
|
||||
|
||||
// Null/Default-constructed QUuids will return MyAvatar
|
||||
Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) override { return new ScriptAvatar(getAvatarBySessionID(avatarID)); }
|
||||
|
||||
AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const override;
|
||||
|
||||
int getNumAvatarsUpdated() const { return _numAvatarsUpdated; }
|
||||
|
|
|
@ -73,10 +73,17 @@ void Head::reset() {
|
|||
void Head::simulate(float deltaTime, bool isMine) {
|
||||
const float NORMAL_HZ = 60.0f; // the update rate the constant values were tuned for
|
||||
|
||||
// grab the audio loudness from the owning avatar, if we have one
|
||||
float audioLoudness = 0.0f;
|
||||
|
||||
if (_owningAvatar) {
|
||||
audioLoudness = _owningAvatar->getAudioLoudness();
|
||||
}
|
||||
|
||||
// Update audio trailing average for rendering facial animations
|
||||
const float AUDIO_AVERAGING_SECS = 0.05f;
|
||||
const float AUDIO_LONG_TERM_AVERAGING_SECS = 30.0f;
|
||||
_averageLoudness = glm::mix(_averageLoudness, _audioLoudness, glm::min(deltaTime / AUDIO_AVERAGING_SECS, 1.0f));
|
||||
_averageLoudness = glm::mix(_averageLoudness, audioLoudness, glm::min(deltaTime / AUDIO_AVERAGING_SECS, 1.0f));
|
||||
|
||||
if (_longTermAverageLoudness == -1.0f) {
|
||||
_longTermAverageLoudness = _averageLoudness;
|
||||
|
@ -154,8 +161,8 @@ void Head::simulate(float deltaTime, bool isMine) {
|
|||
// Update audio attack data for facial animation (eyebrows and mouth)
|
||||
float audioAttackAveragingRate = (10.0f - deltaTime * NORMAL_HZ) / 10.0f; // --> 0.9 at 60 Hz
|
||||
_audioAttack = audioAttackAveragingRate * _audioAttack +
|
||||
(1.0f - audioAttackAveragingRate) * fabs((_audioLoudness - _longTermAverageLoudness) - _lastLoudness);
|
||||
_lastLoudness = (_audioLoudness - _longTermAverageLoudness);
|
||||
(1.0f - audioAttackAveragingRate) * fabs((audioLoudness - _longTermAverageLoudness) - _lastLoudness);
|
||||
_lastLoudness = (audioLoudness - _longTermAverageLoudness);
|
||||
|
||||
const float BROW_LIFT_THRESHOLD = 100.0f;
|
||||
if (_audioAttack > BROW_LIFT_THRESHOLD) {
|
||||
|
|
|
@ -404,8 +404,8 @@ void MyAvatar::update(float deltaTime) {
|
|||
// Also get the AudioClient so we can update the avatar bounding box data
|
||||
// on the AudioClient side.
|
||||
auto audio = DependencyManager::get<AudioClient>();
|
||||
head->setAudioLoudness(audio->getLastInputLoudness());
|
||||
head->setAudioAverageLoudness(audio->getAudioAverageInputLoudness());
|
||||
setAudioLoudness(audio->getLastInputLoudness());
|
||||
setAudioAverageLoudness(audio->getAudioAverageInputLoudness());
|
||||
|
||||
glm::vec3 halfBoundingBoxDimensions(_characterController.getCapsuleRadius(), _characterController.getCapsuleHalfHeight(), _characterController.getCapsuleRadius());
|
||||
halfBoundingBoxDimensions += _characterController.getCapsuleLocalOffset();
|
||||
|
|
146
interface/src/avatar/ScriptAvatar.cpp
Normal file
146
interface/src/avatar/ScriptAvatar.cpp
Normal file
|
@ -0,0 +1,146 @@
|
|||
//
|
||||
// ScriptAvatar.cpp
|
||||
// interface/src/avatars
|
||||
//
|
||||
// Created by Stephen Birarda on 4/10/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ScriptAvatar.h"
|
||||
|
||||
ScriptAvatar::ScriptAvatar(AvatarSharedPointer avatarData) :
|
||||
ScriptAvatarData(avatarData)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<Avatar> ScriptAvatar::lockAvatar() const {
|
||||
if (auto lockedAvatarData = _avatarData.lock()) {
|
||||
return std::dynamic_pointer_cast<Avatar>(lockedAvatarData);
|
||||
} else {
|
||||
return std::shared_ptr<Avatar>();
|
||||
}
|
||||
}
|
||||
|
||||
glm::quat ScriptAvatar::getDefaultJointRotation(int index) const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getDefaultJointRotation(index);
|
||||
} else {
|
||||
return glm::quat();
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 ScriptAvatar::getDefaultJointTranslation(int index) const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getDefaultJointTranslation(index);
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 ScriptAvatar::getSkeletonOffset() const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getSkeletonOffset();
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 ScriptAvatar::getJointPosition(int index) const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getJointPosition(index);
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 ScriptAvatar::getJointPosition(const QString& name) const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getJointPosition(name);
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 ScriptAvatar::getNeckPosition() const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getNeckPosition();
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 ScriptAvatar::getAcceleration() const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getAcceleration();
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
|
||||
QUuid ScriptAvatar::getParentID() const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getParentID();
|
||||
} else {
|
||||
return QUuid();
|
||||
}
|
||||
}
|
||||
|
||||
quint16 ScriptAvatar::getParentJointIndex() const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getParentJointIndex();
|
||||
} else {
|
||||
return INVALID_JOINT_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
QVariantList ScriptAvatar::getSkeleton() const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getSkeleton();
|
||||
} else {
|
||||
return QVariantList();
|
||||
}
|
||||
}
|
||||
|
||||
float ScriptAvatar::getSimulationRate(const QString& rateName) const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getSimulationRate(rateName);
|
||||
} else {
|
||||
return 0.0f;;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 ScriptAvatar::getLeftPalmPosition() const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getLeftPalmPosition();
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
|
||||
glm::quat ScriptAvatar::getLeftPalmRotation() const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getLeftPalmRotation();
|
||||
} else {
|
||||
return glm::quat();
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 ScriptAvatar::getRightPalmPosition() const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getRightPalmPosition();
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
|
||||
glm::quat ScriptAvatar::getRightPalmRotation() const {
|
||||
if (auto lockedAvatar = lockAvatar()) {
|
||||
return lockedAvatar->getRightPalmRotation();
|
||||
} else {
|
||||
return glm::quat();
|
||||
}
|
||||
}
|
56
interface/src/avatar/ScriptAvatar.h
Normal file
56
interface/src/avatar/ScriptAvatar.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// ScriptAvatar.h
|
||||
// interface/src/avatars
|
||||
//
|
||||
// Created by Stephen Birarda on 4/10/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ScriptAvatar_h
|
||||
#define hifi_ScriptAvatar_h
|
||||
|
||||
#include <ScriptAvatarData.h>
|
||||
|
||||
#include "Avatar.h"
|
||||
|
||||
class ScriptAvatar : public ScriptAvatarData {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(glm::vec3 skeletonOffset READ getSkeletonOffset)
|
||||
|
||||
public:
|
||||
ScriptAvatar(AvatarSharedPointer avatarData);
|
||||
|
||||
public slots:
|
||||
|
||||
glm::quat getDefaultJointRotation(int index) const;
|
||||
glm::vec3 getDefaultJointTranslation(int index) const;
|
||||
|
||||
glm::vec3 getSkeletonOffset() const;
|
||||
|
||||
glm::vec3 getJointPosition(int index) const;
|
||||
glm::vec3 getJointPosition(const QString& name) const;
|
||||
glm::vec3 getNeckPosition() const;
|
||||
|
||||
glm::vec3 getAcceleration() const;
|
||||
|
||||
QUuid getParentID() const;
|
||||
quint16 getParentJointIndex() const;
|
||||
|
||||
QVariantList getSkeleton() const;
|
||||
|
||||
float getSimulationRate(const QString& rateName = QString("")) const;
|
||||
|
||||
glm::vec3 getLeftPalmPosition() const;
|
||||
glm::quat getLeftPalmRotation() const;
|
||||
glm::vec3 getRightPalmPosition() const;
|
||||
glm::quat getRightPalmRotation() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Avatar> lockAvatar() const;
|
||||
};
|
||||
|
||||
#endif // hifi_ScriptAvatar_h
|
|
@ -240,8 +240,8 @@ void SkeletonModel::updateAttitude() {
|
|||
// Called by Avatar::simulate after it has set the joint states (fullUpdate true if changed),
|
||||
// but just before head has been simulated.
|
||||
void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
|
||||
updateAttitude();
|
||||
if (fullUpdate) {
|
||||
updateAttitude();
|
||||
setBlendshapeCoefficients(_owningAvatar->getHead()->getBlendshapeCoefficients());
|
||||
|
||||
Model::simulate(deltaTime, fullUpdate);
|
||||
|
|
|
@ -71,9 +71,10 @@ signals:
|
|||
void domainChanged(const QString& domainHostname);
|
||||
void svoImportRequested(const QString& url);
|
||||
void domainConnectionRefused(const QString& reasonMessage, int reasonCode, const QString& extraInfo);
|
||||
void snapshotTaken(const QString& pathStillSnapshot, const QString& pathAnimatedSnapshot, bool notify);
|
||||
void stillSnapshotTaken(const QString& pathStillSnapshot, bool notify);
|
||||
void snapshotShared(const QString& error);
|
||||
void processingGif();
|
||||
void processingGifStarted(const QString& pathStillSnapshot);
|
||||
void processingGifCompleted(const QString& pathAnimatedSnapshot);
|
||||
|
||||
void connectionAdded(const QString& connectionName);
|
||||
void connectionError(const QString& errorString);
|
||||
|
|
|
@ -86,7 +86,8 @@ void SnapshotAnimated::captureFrames() {
|
|||
SnapshotAnimated::snapshotAnimatedTimerRunning = false;
|
||||
|
||||
// Notify the user that we're processing the snapshot
|
||||
emit SnapshotAnimated::snapshotAnimatedDM->processingGif();
|
||||
// This also pops up the "Share" dialog. The unprocessed GIF will be visualized as a loading icon until processingGifCompleted() is called.
|
||||
emit SnapshotAnimated::snapshotAnimatedDM->processingGifStarted(SnapshotAnimated::snapshotStillPath);
|
||||
|
||||
// Kick off the thread that'll pack the frames into the GIF
|
||||
QtConcurrent::run(processFrames);
|
||||
|
@ -132,7 +133,7 @@ void SnapshotAnimated::processFrames() {
|
|||
// Reset the current frame timestamp
|
||||
SnapshotAnimated::snapshotAnimatedTimestamp = 0;
|
||||
SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp = 0;
|
||||
|
||||
// Let the window scripting interface know that the snapshots have been taken.
|
||||
emit SnapshotAnimated::snapshotAnimatedDM->snapshotTaken(SnapshotAnimated::snapshotStillPath, SnapshotAnimated::snapshotAnimatedPath, false);
|
||||
|
||||
// Update the "Share" dialog with the processed GIF.
|
||||
emit SnapshotAnimated::snapshotAnimatedDM->processingGifCompleted(SnapshotAnimated::snapshotAnimatedPath);
|
||||
}
|
||||
|
|
|
@ -352,7 +352,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
|||
if (hasAudioLoudness) {
|
||||
auto startSection = destinationBuffer;
|
||||
auto data = reinterpret_cast<AvatarDataPacket::AudioLoudness*>(destinationBuffer);
|
||||
data->audioLoudness = packFloatGainToByte(_headData->getAudioLoudness() / AUDIO_LOUDNESS_SCALE);
|
||||
data->audioLoudness = packFloatGainToByte(getAudioLoudness() / AUDIO_LOUDNESS_SCALE);
|
||||
destinationBuffer += sizeof(AvatarDataPacket::AudioLoudness);
|
||||
|
||||
int numBytes = destinationBuffer - startSection;
|
||||
|
@ -836,7 +836,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
|
|||
}
|
||||
return buffer.size();
|
||||
}
|
||||
_headData->setAudioLoudness(audioLoudness);
|
||||
setAudioLoudness(audioLoudness);
|
||||
int numBytesRead = sourceBuffer - startSection;
|
||||
_audioLoudnessRate.increment(numBytesRead);
|
||||
_audioLoudnessUpdateRate.increment();
|
||||
|
|
|
@ -448,10 +448,18 @@ public:
|
|||
void setHeadRoll(float value) { _headData->setBaseRoll(value); }
|
||||
|
||||
// access to Head().set/getAverageLoudness
|
||||
float getAudioLoudness() const { return _headData->getAudioLoudness(); }
|
||||
void setAudioLoudness(float value) { _headData->setAudioLoudness(value); }
|
||||
float getAudioAverageLoudness() const { return _headData->getAudioAverageLoudness(); }
|
||||
void setAudioAverageLoudness(float value) { _headData->setAudioAverageLoudness(value); }
|
||||
|
||||
float getAudioLoudness() const { return _audioLoudness; }
|
||||
void setAudioLoudness(float audioLoudness) {
|
||||
if (audioLoudness != _audioLoudness) {
|
||||
_audioLoudnessChanged = usecTimestampNow();
|
||||
}
|
||||
_audioLoudness = audioLoudness;
|
||||
}
|
||||
bool audioLoudnessChangedSince(quint64 time) const { return _audioLoudnessChanged >= time; }
|
||||
|
||||
float getAudioAverageLoudness() const { return _audioAverageLoudness; }
|
||||
void setAudioAverageLoudness(float audioAverageLoudness) { _audioAverageLoudness = audioAverageLoudness; }
|
||||
|
||||
// Scale
|
||||
virtual void setTargetScale(float targetScale);
|
||||
|
@ -642,7 +650,6 @@ protected:
|
|||
bool avatarBoundingBoxChangedSince(quint64 time) const { return _avatarBoundingBoxChanged >= time; }
|
||||
bool avatarScaleChangedSince(quint64 time) const { return _avatarScaleChanged >= time; }
|
||||
bool lookAtPositionChangedSince(quint64 time) const { return _headData->lookAtPositionChangedSince(time); }
|
||||
bool audioLoudnessChangedSince(quint64 time) const { return _headData->audioLoudnessChangedSince(time); }
|
||||
bool sensorToWorldMatrixChangedSince(quint64 time) const { return _sensorToWorldMatrixChanged >= time; }
|
||||
bool additionalFlagsChangedSince(quint64 time) const { return _additionalFlagsChanged >= time; }
|
||||
bool parentInfoChangedSince(quint64 time) const { return _parentChanged >= time; }
|
||||
|
@ -768,6 +775,10 @@ protected:
|
|||
|
||||
int getFauxJointIndex(const QString& name) const;
|
||||
|
||||
float _audioLoudness { 0.0f };
|
||||
quint64 _audioLoudnessChanged { 0 };
|
||||
float _audioAverageLoudness { 0.0f };
|
||||
|
||||
private:
|
||||
friend void avatarStateFromFrame(const QByteArray& frameData, AvatarData* _avatar);
|
||||
static QUrl _defaultFullAvatarModelUrl;
|
||||
|
|
|
@ -30,11 +30,6 @@ QVector<QUuid> AvatarHashMap::getAvatarIdentifiers() {
|
|||
return _avatarHash.keys().toVector();
|
||||
}
|
||||
|
||||
AvatarData* AvatarHashMap::getAvatar(QUuid avatarID) {
|
||||
// Null/Default-constructed QUuids will return MyAvatar
|
||||
return getAvatarBySessionID(avatarID).get();
|
||||
}
|
||||
|
||||
bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range) {
|
||||
auto hashCopy = getHashCopy();
|
||||
foreach(const AvatarSharedPointer& sharedAvatar, hashCopy) {
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <NLPacket.h>
|
||||
#include <Node.h>
|
||||
|
||||
#include "ScriptAvatarData.h"
|
||||
|
||||
#include "AvatarData.h"
|
||||
|
||||
class AvatarHashMap : public QObject, public Dependency {
|
||||
|
@ -37,7 +39,9 @@ public:
|
|||
|
||||
// Currently, your own avatar will be included as the null avatar id.
|
||||
Q_INVOKABLE QVector<QUuid> getAvatarIdentifiers();
|
||||
Q_INVOKABLE AvatarData* getAvatar(QUuid avatarID);
|
||||
|
||||
// Null/Default-constructed QUuids will return MyAvatar
|
||||
virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); }
|
||||
|
||||
virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const { return findAvatar(sessionID); }
|
||||
int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters);
|
||||
|
|
|
@ -32,14 +32,12 @@ HeadData::HeadData(AvatarData* owningAvatar) :
|
|||
_basePitch(0.0f),
|
||||
_baseRoll(0.0f),
|
||||
_lookAtPosition(0.0f, 0.0f, 0.0f),
|
||||
_audioLoudness(0.0f),
|
||||
_isFaceTrackerConnected(false),
|
||||
_isEyeTrackerConnected(false),
|
||||
_leftEyeBlink(0.0f),
|
||||
_rightEyeBlink(0.0f),
|
||||
_averageLoudness(0.0f),
|
||||
_browAudioLift(0.0f),
|
||||
_audioAverageLoudness(0.0f),
|
||||
_owningAvatar(owningAvatar)
|
||||
{
|
||||
|
||||
|
|
|
@ -57,18 +57,6 @@ public:
|
|||
glm::quat getOrientation() const;
|
||||
void setOrientation(const glm::quat& orientation);
|
||||
|
||||
float getAudioLoudness() const { return _audioLoudness; }
|
||||
void setAudioLoudness(float audioLoudness) {
|
||||
if (audioLoudness != _audioLoudness) {
|
||||
_audioLoudnessChanged = usecTimestampNow();
|
||||
}
|
||||
_audioLoudness = audioLoudness;
|
||||
}
|
||||
bool audioLoudnessChangedSince(quint64 time) { return _audioLoudnessChanged >= time; }
|
||||
|
||||
float getAudioAverageLoudness() const { return _audioAverageLoudness; }
|
||||
void setAudioAverageLoudness(float audioAverageLoudness) { _audioAverageLoudness = audioAverageLoudness; }
|
||||
|
||||
void setBlendshape(QString name, float val);
|
||||
const QVector<float>& getBlendshapeCoefficients() const { return _blendshapeCoefficients; }
|
||||
void setBlendshapeCoefficients(const QVector<float>& blendshapeCoefficients) { _blendshapeCoefficients = blendshapeCoefficients; }
|
||||
|
@ -96,16 +84,13 @@ protected:
|
|||
glm::vec3 _lookAtPosition;
|
||||
quint64 _lookAtPositionChanged { 0 };
|
||||
|
||||
float _audioLoudness;
|
||||
quint64 _audioLoudnessChanged { 0 };
|
||||
|
||||
bool _isFaceTrackerConnected;
|
||||
bool _isEyeTrackerConnected;
|
||||
float _leftEyeBlink;
|
||||
float _rightEyeBlink;
|
||||
float _averageLoudness;
|
||||
float _browAudioLift;
|
||||
float _audioAverageLoudness;
|
||||
|
||||
QVector<float> _blendshapeCoefficients;
|
||||
AvatarData* _owningAvatar;
|
||||
|
||||
|
|
314
libraries/avatars/src/ScriptAvatarData.cpp
Normal file
314
libraries/avatars/src/ScriptAvatarData.cpp
Normal file
|
@ -0,0 +1,314 @@
|
|||
//
|
||||
// ScriptAvatarData.cpp
|
||||
// libraries/script-engine/src
|
||||
//
|
||||
// Created by Zach Fox on 2017-04-10.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ScriptAvatarData.h"
|
||||
|
||||
ScriptAvatarData::ScriptAvatarData(AvatarSharedPointer avatarData) :
|
||||
_avatarData(avatarData)
|
||||
{
|
||||
QObject::connect(avatarData.get(), &AvatarData::displayNameChanged, this, &ScriptAvatarData::displayNameChanged);
|
||||
}
|
||||
|
||||
//
|
||||
// PHYSICAL PROPERTIES: POSITION AND ORIENTATION
|
||||
// START
|
||||
//
|
||||
glm::vec3 ScriptAvatarData::getPosition() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getPosition();
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
float ScriptAvatarData::getTargetScale() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getTargetScale();
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
glm::vec3 ScriptAvatarData::getHandPosition() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getHandPosition();
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
float ScriptAvatarData::getBodyPitch() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getBodyPitch();
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
float ScriptAvatarData::getBodyYaw() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getBodyYaw();
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
float ScriptAvatarData::getBodyRoll() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getBodyRoll();
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
glm::quat ScriptAvatarData::getOrientation() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getOrientation();
|
||||
} else {
|
||||
return glm::quat();
|
||||
}
|
||||
}
|
||||
glm::quat ScriptAvatarData::getHeadOrientation() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getHeadOrientation();
|
||||
} else {
|
||||
return glm::quat();
|
||||
}
|
||||
}
|
||||
float ScriptAvatarData::getHeadPitch() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getHeadPitch();
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
float ScriptAvatarData::getHeadYaw() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getHeadYaw();
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
float ScriptAvatarData::getHeadRoll() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getHeadRoll();
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
//
|
||||
// PHYSICAL PROPERTIES: POSITION AND ORIENTATION
|
||||
// END
|
||||
//
|
||||
|
||||
//
|
||||
// PHYSICAL PROPERTIES: VELOCITY
|
||||
// START
|
||||
//
|
||||
glm::vec3 ScriptAvatarData::getVelocity() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getVelocity();
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
glm::vec3 ScriptAvatarData::getAngularVelocity() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getAngularVelocity();
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
//
|
||||
// PHYSICAL PROPERTIES: VELOCITY
|
||||
// END
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// IDENTIFIER PROPERTIES
|
||||
// START
|
||||
//
|
||||
QUuid ScriptAvatarData::getSessionUUID() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getSessionUUID();
|
||||
} else {
|
||||
return QUuid();
|
||||
}
|
||||
}
|
||||
QString ScriptAvatarData::getDisplayName() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getDisplayName();
|
||||
} else {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
QString ScriptAvatarData::getSessionDisplayName() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getSessionDisplayName();
|
||||
} else {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
//
|
||||
// IDENTIFIER PROPERTIES
|
||||
// END
|
||||
//
|
||||
|
||||
//
|
||||
// ATTACHMENT AND JOINT PROPERTIES
|
||||
// START
|
||||
//
|
||||
QString ScriptAvatarData::getSkeletonModelURLFromScript() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getSkeletonModelURLFromScript();
|
||||
} else {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
char ScriptAvatarData::getHandState() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getHandState();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
glm::quat ScriptAvatarData::getJointRotation(int index) const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getJointRotation(index);
|
||||
} else {
|
||||
return glm::quat();
|
||||
}
|
||||
}
|
||||
glm::vec3 ScriptAvatarData::getJointTranslation(int index) const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getJointTranslation(index);
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
glm::quat ScriptAvatarData::getJointRotation(const QString& name) const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getJointRotation(name);
|
||||
} else {
|
||||
return glm::quat();
|
||||
}
|
||||
}
|
||||
glm::vec3 ScriptAvatarData::getJointTranslation(const QString& name) const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getJointTranslation(name);
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
||||
QVector<glm::quat> ScriptAvatarData::getJointRotations() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getJointRotations();
|
||||
} else {
|
||||
return QVector<glm::quat>();
|
||||
}
|
||||
}
|
||||
bool ScriptAvatarData::isJointDataValid(const QString& name) const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->isJointDataValid(name);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int ScriptAvatarData::getJointIndex(const QString& name) const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getJointIndex(name);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
QStringList ScriptAvatarData::getJointNames() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getJointNames();
|
||||
} else {
|
||||
return QStringList();
|
||||
}
|
||||
}
|
||||
QVector<AttachmentData> ScriptAvatarData::getAttachmentData() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getAttachmentData();
|
||||
} else {
|
||||
return QVector<AttachmentData>();
|
||||
}
|
||||
}
|
||||
//
|
||||
// ATTACHMENT AND JOINT PROPERTIES
|
||||
// END
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// AUDIO PROPERTIES
|
||||
// START
|
||||
//
|
||||
float ScriptAvatarData::getAudioLoudness() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getAudioLoudness();
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
float ScriptAvatarData::getAudioAverageLoudness() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getAudioAverageLoudness();
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
//
|
||||
// AUDIO PROPERTIES
|
||||
// END
|
||||
//
|
||||
|
||||
//
|
||||
// MATRIX PROPERTIES
|
||||
// START
|
||||
//
|
||||
glm::mat4 ScriptAvatarData::getSensorToWorldMatrix() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getSensorToWorldMatrix();
|
||||
} else {
|
||||
return glm::mat4();
|
||||
}
|
||||
}
|
||||
glm::mat4 ScriptAvatarData::getControllerLeftHandMatrix() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getControllerLeftHandMatrix();
|
||||
} else {
|
||||
return glm::mat4();
|
||||
}
|
||||
}
|
||||
glm::mat4 ScriptAvatarData::getControllerRightHandMatrix() const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getControllerRightHandMatrix();
|
||||
} else {
|
||||
return glm::mat4();
|
||||
}
|
||||
}
|
||||
//
|
||||
// MATRIX PROPERTIES
|
||||
// END
|
||||
//
|
||||
|
||||
glm::quat ScriptAvatarData::getAbsoluteJointRotationInObjectFrame(int index) const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getAbsoluteJointRotationInObjectFrame(index);
|
||||
} else {
|
||||
return glm::quat();
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 ScriptAvatarData::getAbsoluteJointTranslationInObjectFrame(int index) const {
|
||||
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
|
||||
return sharedAvatarData->getAbsoluteJointTranslationInObjectFrame(index);
|
||||
} else {
|
||||
return glm::vec3();
|
||||
}
|
||||
}
|
138
libraries/avatars/src/ScriptAvatarData.h
Normal file
138
libraries/avatars/src/ScriptAvatarData.h
Normal file
|
@ -0,0 +1,138 @@
|
|||
//
|
||||
// ScriptAvatarData.h
|
||||
// libraries/script-engine/src
|
||||
//
|
||||
// Created by Zach Fox on 2017-04-10.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ScriptAvatarData_h
|
||||
#define hifi_ScriptAvatarData_h
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "AvatarData.h"
|
||||
|
||||
class ScriptAvatarData : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
//
|
||||
// PHYSICAL PROPERTIES: POSITION AND ORIENTATION
|
||||
//
|
||||
Q_PROPERTY(glm::vec3 position READ getPosition)
|
||||
Q_PROPERTY(float scale READ getTargetScale)
|
||||
Q_PROPERTY(glm::vec3 handPosition READ getHandPosition)
|
||||
Q_PROPERTY(float bodyPitch READ getBodyPitch)
|
||||
Q_PROPERTY(float bodyYaw READ getBodyYaw)
|
||||
Q_PROPERTY(float bodyRoll READ getBodyRoll)
|
||||
Q_PROPERTY(glm::quat orientation READ getOrientation)
|
||||
Q_PROPERTY(glm::quat headOrientation READ getHeadOrientation)
|
||||
Q_PROPERTY(float headPitch READ getHeadPitch)
|
||||
Q_PROPERTY(float headYaw READ getHeadYaw)
|
||||
Q_PROPERTY(float headRoll READ getHeadRoll)
|
||||
//
|
||||
// PHYSICAL PROPERTIES: VELOCITY
|
||||
//
|
||||
Q_PROPERTY(glm::vec3 velocity READ getVelocity)
|
||||
Q_PROPERTY(glm::vec3 angularVelocity READ getAngularVelocity)
|
||||
|
||||
//
|
||||
// IDENTIFIER PROPERTIES
|
||||
//
|
||||
Q_PROPERTY(QUuid sessionUUID READ getSessionUUID)
|
||||
Q_PROPERTY(QString displayName READ getDisplayName NOTIFY displayNameChanged)
|
||||
Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName)
|
||||
|
||||
//
|
||||
// ATTACHMENT AND JOINT PROPERTIES
|
||||
//
|
||||
Q_PROPERTY(QString skeletonModelURL READ getSkeletonModelURLFromScript)
|
||||
Q_PROPERTY(QVector<AttachmentData> attachmentData READ getAttachmentData)
|
||||
Q_PROPERTY(QStringList jointNames READ getJointNames)
|
||||
|
||||
//
|
||||
// AUDIO PROPERTIES
|
||||
//
|
||||
Q_PROPERTY(float audioLoudness READ getAudioLoudness)
|
||||
Q_PROPERTY(float audioAverageLoudness READ getAudioAverageLoudness)
|
||||
|
||||
//
|
||||
// MATRIX PROPERTIES
|
||||
//
|
||||
Q_PROPERTY(glm::mat4 sensorToWorldMatrix READ getSensorToWorldMatrix)
|
||||
Q_PROPERTY(glm::mat4 controllerLeftHandMatrix READ getControllerLeftHandMatrix)
|
||||
Q_PROPERTY(glm::mat4 controllerRightHandMatrix READ getControllerRightHandMatrix)
|
||||
|
||||
public:
|
||||
ScriptAvatarData(AvatarSharedPointer avatarData);
|
||||
|
||||
//
|
||||
// PHYSICAL PROPERTIES: POSITION AND ORIENTATION
|
||||
//
|
||||
glm::vec3 getPosition() const;
|
||||
float getTargetScale() const;
|
||||
glm::vec3 getHandPosition() const;
|
||||
float getBodyPitch() const;
|
||||
float getBodyYaw() const;
|
||||
float getBodyRoll() const;
|
||||
glm::quat getOrientation() const;
|
||||
glm::quat getHeadOrientation() const;
|
||||
float getHeadPitch() const;
|
||||
float getHeadYaw() const;
|
||||
float getHeadRoll() const;
|
||||
//
|
||||
// PHYSICAL PROPERTIES: VELOCITY
|
||||
//
|
||||
glm::vec3 getVelocity() const;
|
||||
glm::vec3 getAngularVelocity() const;
|
||||
|
||||
//
|
||||
// IDENTIFIER PROPERTIES
|
||||
//
|
||||
QUuid getSessionUUID() const;
|
||||
QString getDisplayName() const;
|
||||
QString getSessionDisplayName() const;
|
||||
|
||||
//
|
||||
// ATTACHMENT AND JOINT PROPERTIES
|
||||
//
|
||||
QString getSkeletonModelURLFromScript() const;
|
||||
Q_INVOKABLE char getHandState() const;
|
||||
Q_INVOKABLE glm::quat getJointRotation(int index) const;
|
||||
Q_INVOKABLE glm::vec3 getJointTranslation(int index) const;
|
||||
Q_INVOKABLE glm::quat getJointRotation(const QString& name) const;
|
||||
Q_INVOKABLE glm::vec3 getJointTranslation(const QString& name) const;
|
||||
Q_INVOKABLE QVector<glm::quat> getJointRotations() const;
|
||||
Q_INVOKABLE bool isJointDataValid(const QString& name) const;
|
||||
Q_INVOKABLE int getJointIndex(const QString& name) const;
|
||||
Q_INVOKABLE QStringList getJointNames() const;
|
||||
Q_INVOKABLE QVector<AttachmentData> getAttachmentData() const;
|
||||
|
||||
//
|
||||
// AUDIO PROPERTIES
|
||||
//
|
||||
float getAudioLoudness() const;
|
||||
float getAudioAverageLoudness() const;
|
||||
|
||||
//
|
||||
// MATRIX PROPERTIES
|
||||
//
|
||||
glm::mat4 getSensorToWorldMatrix() const;
|
||||
glm::mat4 getControllerLeftHandMatrix() const;
|
||||
glm::mat4 getControllerRightHandMatrix() const;
|
||||
|
||||
signals:
|
||||
void displayNameChanged();
|
||||
|
||||
public slots:
|
||||
glm::quat getAbsoluteJointRotationInObjectFrame(int index) const;
|
||||
glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const;
|
||||
|
||||
protected:
|
||||
std::weak_ptr<AvatarData> _avatarData;
|
||||
};
|
||||
|
||||
#endif // hifi_ScriptAvatarData_h
|
|
@ -608,11 +608,19 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori
|
|||
face, surfaceNormal, extraInfo, precisionPicking);
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::getCollisionGeometryResource() {
|
||||
QUrl hullURL(getCompoundShapeURL());
|
||||
QUrlQuery queryArgs(hullURL);
|
||||
queryArgs.addQueryItem("collision-hull", "");
|
||||
hullURL.setQuery(queryArgs);
|
||||
_compoundShapeResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(hullURL);
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::setShapeType(ShapeType type) {
|
||||
ModelEntityItem::setShapeType(type);
|
||||
if (getShapeType() == SHAPE_TYPE_COMPOUND) {
|
||||
if (!_compoundShapeResource && !getCompoundShapeURL().isEmpty()) {
|
||||
_compoundShapeResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(getCompoundShapeURL());
|
||||
getCollisionGeometryResource();
|
||||
}
|
||||
} else if (_compoundShapeResource && !getCompoundShapeURL().isEmpty()) {
|
||||
// the compoundURL has been set but the shapeType does not agree
|
||||
|
@ -626,11 +634,7 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) {
|
|||
// will end up in a different hash-key in ResourceCache. TODO: It would be better to use the same URL and
|
||||
// parse it twice.
|
||||
auto currentCompoundShapeURL = getCompoundShapeURL();
|
||||
QUrl hullURL(url);
|
||||
QUrlQuery queryArgs(hullURL);
|
||||
queryArgs.addQueryItem("collision-hull", "");
|
||||
hullURL.setQuery(queryArgs);
|
||||
ModelEntityItem::setCompoundShapeURL(hullURL.toString());
|
||||
ModelEntityItem::setCompoundShapeURL(url);
|
||||
|
||||
if (getCompoundShapeURL() != currentCompoundShapeURL || !_model) {
|
||||
EntityTreePointer tree = getTree();
|
||||
|
@ -638,7 +642,7 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) {
|
|||
QMetaObject::invokeMethod(tree.get(), "callLoader", Qt::QueuedConnection, Q_ARG(EntityItemID, getID()));
|
||||
}
|
||||
if (getShapeType() == SHAPE_TYPE_COMPOUND) {
|
||||
_compoundShapeResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(hullURL);
|
||||
getCollisionGeometryResource();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -670,8 +674,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() {
|
|||
}
|
||||
return true;
|
||||
} else if (!getCompoundShapeURL().isEmpty()) {
|
||||
_compoundShapeResource =
|
||||
DependencyManager::get<ModelCache>()->getCollisionGeometryResource(getCompoundShapeURL());
|
||||
getCollisionGeometryResource();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ private:
|
|||
QVariantMap parseTexturesToMap(QString textures);
|
||||
void remapTextures();
|
||||
|
||||
void getCollisionGeometryResource();
|
||||
GeometryResource::Pointer _compoundShapeResource;
|
||||
ModelPointer _model = nullptr;
|
||||
bool _needsInitialSimulation = true;
|
||||
|
|
|
@ -56,7 +56,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||
case PacketType::AvatarData:
|
||||
case PacketType::BulkAvatarData:
|
||||
case PacketType::KillAvatar:
|
||||
return static_cast<PacketVersion>(AvatarMixerPacketVersion::AvatarAsChildFixes);
|
||||
return static_cast<PacketVersion>(AvatarMixerPacketVersion::StickAndBallDefaultAvatar);
|
||||
case PacketType::MessagesData:
|
||||
return static_cast<PacketVersion>(MessageDataVersion::TextOrBinaryData);
|
||||
case PacketType::ICEServerHeartbeat:
|
||||
|
|
|
@ -228,7 +228,8 @@ enum class AvatarMixerPacketVersion : PacketVersion {
|
|||
Unignore,
|
||||
ImmediateSessionDisplayNameUpdates,
|
||||
VariableAvatarData,
|
||||
AvatarAsChildFixes
|
||||
AvatarAsChildFixes,
|
||||
StickAndBallDefaultAvatar
|
||||
};
|
||||
|
||||
enum class DomainConnectRequestVersion : PacketVersion {
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <PathUtils.h>
|
||||
#include <ResourceScriptingInterface.h>
|
||||
#include <NodeList.h>
|
||||
#include <ScriptAvatarData.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <UUID.h>
|
||||
#include <ui/Menu.h>
|
||||
|
@ -59,6 +60,7 @@
|
|||
#include "FileScriptingInterface.h" // unzip project
|
||||
#include "MenuItemProperties.h"
|
||||
#include "ScriptAudioInjector.h"
|
||||
#include "ScriptAvatarData.h"
|
||||
#include "ScriptCache.h"
|
||||
#include "ScriptEngineLogging.h"
|
||||
#include "ScriptEngine.h"
|
||||
|
@ -111,14 +113,6 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine) {
|
|||
return QScriptValue();
|
||||
}
|
||||
|
||||
QScriptValue avatarDataToScriptValue(QScriptEngine* engine, AvatarData* const &in) {
|
||||
return engine->newQObject(in, QScriptEngine::QtOwnership, DEFAULT_QOBJECT_WRAP_OPTIONS);
|
||||
}
|
||||
|
||||
void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) {
|
||||
out = qobject_cast<AvatarData*>(object.toQObject());
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(controller::InputController*)
|
||||
//static int inputControllerPointerId = qRegisterMetaType<controller::InputController*>();
|
||||
|
||||
|
@ -542,6 +536,16 @@ static QScriptValue createScriptableResourcePrototype(QScriptEngine* engine) {
|
|||
return prototype;
|
||||
}
|
||||
|
||||
QScriptValue avatarDataToScriptValue(QScriptEngine* engine, ScriptAvatarData* const& in) {
|
||||
return engine->newQObject(in, QScriptEngine::ScriptOwnership, DEFAULT_QOBJECT_WRAP_OPTIONS);
|
||||
}
|
||||
|
||||
void avatarDataFromScriptValue(const QScriptValue& object, ScriptAvatarData*& out) {
|
||||
// This is not implemented because there are no slots/properties that take an AvatarSharedPointer from a script
|
||||
assert(false);
|
||||
out = nullptr;
|
||||
}
|
||||
|
||||
void ScriptEngine::resetModuleCache(bool deleteScriptCache) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
executeOnScriptThread([=]() { resetModuleCache(deleteScriptCache); });
|
||||
|
|
|
@ -49,13 +49,14 @@ QObject* TabletScriptingInterface::getTablet(const QString& tabletId) {
|
|||
auto iter = _tabletProxies.find(tabletId);
|
||||
if (iter != _tabletProxies.end()) {
|
||||
// tablet already exists, just return it.
|
||||
return iter->second.data();
|
||||
return iter->second;
|
||||
} else {
|
||||
// allocate a new tablet, add it to the map then return it.
|
||||
auto tabletProxy = QSharedPointer<TabletProxy>(new TabletProxy(tabletId));
|
||||
auto tabletProxy = new TabletProxy(tabletId);
|
||||
tabletProxy->setParent(this);
|
||||
_tabletProxies[tabletId] = tabletProxy;
|
||||
tabletProxy->setToolbarMode(_toolbarMode);
|
||||
return tabletProxy.data();
|
||||
return tabletProxy;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +177,6 @@ class TabletRootWindow : public QmlWindowClass {
|
|||
};
|
||||
|
||||
TabletProxy::TabletProxy(QString name) : _name(name) {
|
||||
|
||||
}
|
||||
|
||||
void TabletProxy::setToolbarMode(bool toolbarMode) {
|
||||
|
@ -354,6 +354,38 @@ void TabletProxy::gotoMenuScreen(const QString& submenu) {
|
|||
}
|
||||
}
|
||||
|
||||
void TabletProxy::loadQMLOnTop(const QVariant& path) {
|
||||
QObject* root = nullptr;
|
||||
if (!_toolbarMode && _qmlTabletRoot) {
|
||||
root = _qmlTabletRoot;
|
||||
} else if (_toolbarMode && _desktopWindow) {
|
||||
root = _desktopWindow->asQuickItem();
|
||||
}
|
||||
|
||||
if (root) {
|
||||
QMetaObject::invokeMethod(root, "loadQMLOnTop", Q_ARG(const QVariant&, path));
|
||||
QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true)));
|
||||
} else {
|
||||
qCDebug(scriptengine) << "tablet cannot load QML because _qmlTabletRoot is null";
|
||||
}
|
||||
}
|
||||
|
||||
void TabletProxy::returnToPreviousApp() {
|
||||
QObject* root = nullptr;
|
||||
if (!_toolbarMode && _qmlTabletRoot) {
|
||||
root = _qmlTabletRoot;
|
||||
} else if (_toolbarMode && _desktopWindow) {
|
||||
root = _desktopWindow->asQuickItem();
|
||||
}
|
||||
|
||||
if (root) {
|
||||
QMetaObject::invokeMethod(root, "returnToPreviousApp");
|
||||
QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true)));
|
||||
} else {
|
||||
qCDebug(scriptengine) << "tablet cannot load QML because _qmlTabletRoot is null";
|
||||
}
|
||||
}
|
||||
|
||||
void TabletProxy::loadQMLSource(const QVariant& path) {
|
||||
|
||||
QObject* root = nullptr;
|
||||
|
@ -440,6 +472,26 @@ void TabletProxy::gotoWebScreen(const QString& url) {
|
|||
gotoWebScreen(url, "");
|
||||
}
|
||||
|
||||
void TabletProxy::loadWebScreenOnTop(const QVariant& url) {
|
||||
loadWebScreenOnTop(url, "");
|
||||
}
|
||||
|
||||
void TabletProxy::loadWebScreenOnTop(const QVariant& url, const QString& injectJavaScriptUrl) {
|
||||
QObject* root = nullptr;
|
||||
if (!_toolbarMode && _qmlTabletRoot) {
|
||||
root = _qmlTabletRoot;
|
||||
} else if (_toolbarMode && _desktopWindow) {
|
||||
root = _desktopWindow->asQuickItem();
|
||||
}
|
||||
|
||||
if (root) {
|
||||
QMetaObject::invokeMethod(root, "loadQMLOnTop", Q_ARG(const QVariant&, QVariant(WEB_VIEW_SOURCE_URL)));
|
||||
QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true)));
|
||||
QMetaObject::invokeMethod(root, "loadWebOnTop", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectJavaScriptUrl)));
|
||||
}
|
||||
_state = State::Web;
|
||||
}
|
||||
|
||||
void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaScriptUrl) {
|
||||
|
||||
QObject* root = nullptr;
|
||||
|
|
|
@ -70,7 +70,7 @@ private:
|
|||
|
||||
protected:
|
||||
std::mutex _mutex;
|
||||
std::map<QString, QSharedPointer<TabletProxy>> _tabletProxies;
|
||||
std::map<QString, TabletProxy*> _tabletProxies;
|
||||
QObject* _toolbarScriptingInterface { nullptr };
|
||||
bool _toolbarMode { false };
|
||||
};
|
||||
|
@ -99,7 +99,7 @@ public:
|
|||
bool getToolbarMode() const { return _toolbarMode; }
|
||||
void setToolbarMode(bool toolbarMode);
|
||||
|
||||
void initialScreen(const QVariant& url);
|
||||
Q_INVOKABLE void initialScreen(const QVariant& url);
|
||||
|
||||
/**jsdoc
|
||||
* transition to the home screen
|
||||
|
@ -120,6 +120,13 @@ public:
|
|||
Q_INVOKABLE void pushOntoStack(const QVariant& path);
|
||||
Q_INVOKABLE void popFromStack();
|
||||
|
||||
Q_INVOKABLE void loadQMLOnTop(const QVariant& path);
|
||||
Q_INVOKABLE void loadWebScreenOnTop(const QVariant& url);
|
||||
Q_INVOKABLE void loadWebScreenOnTop(const QVariant& url, const QString& injectedJavaScriptUrl);
|
||||
Q_INVOKABLE void returnToPreviousApp();
|
||||
|
||||
|
||||
|
||||
/** jsdoc
|
||||
* Check if the tablet has a message dialog open
|
||||
* @function TabletProxy#isMessageDialogOpen
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
|
||||
void addSample(T sample) {
|
||||
if (numSamples > 0) {
|
||||
average = ((float)sample * WEIGHTING) + ((float)average * ONE_MINUS_WEIGHTING);
|
||||
average = (sample * WEIGHTING) + (average * ONE_MINUS_WEIGHTING);
|
||||
} else {
|
||||
average = sample;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
Q_DECLARE_LOGGING_CATEGORY(inputplugins)
|
||||
Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins")
|
||||
|
||||
|
||||
const char* KinectPlugin::NAME = "Kinect";
|
||||
const char* KinectPlugin::KINECT_ID_STRING = "Kinect";
|
||||
|
||||
|
@ -493,11 +492,23 @@ void KinectPlugin::ProcessBody(INT64 time, int bodyCount, IBody** bodies) {
|
|||
//_joints[j].orientation = jointOrientation;
|
||||
if (joints[j].JointType == JointType_HandRight) {
|
||||
static const quat kinectToHandRight = glm::angleAxis(-PI / 2.0f, Vectors::UNIT_Y);
|
||||
_joints[j].orientation = jointOrientation * kinectToHandRight;
|
||||
// add moving average of orientation quaternion
|
||||
glm::quat jointSample = jointOrientation * kinectToHandRight;
|
||||
if (glm::dot(jointSample, _RightHandOrientationAverage.getAverage()) < 0) {
|
||||
jointSample = -jointSample;
|
||||
}
|
||||
_RightHandOrientationAverage.addSample(jointSample);
|
||||
_joints[j].orientation = glm::normalize(_RightHandOrientationAverage.getAverage());
|
||||
} else if (joints[j].JointType == JointType_HandLeft) {
|
||||
// To transform from Kinect to our LEFT Hand.... Postive 90 deg around Y
|
||||
static const quat kinectToHandLeft = glm::angleAxis(PI / 2.0f, Vectors::UNIT_Y);
|
||||
_joints[j].orientation = jointOrientation * kinectToHandLeft;
|
||||
// add moving average of orientation quaternion
|
||||
glm::quat jointSample = jointOrientation * kinectToHandLeft;
|
||||
if (glm::dot(jointSample, _LeftHandOrientationAverage.getAverage()) < 0) {
|
||||
jointSample = -jointSample;
|
||||
}
|
||||
_LeftHandOrientationAverage.addSample(jointSample);
|
||||
_joints[j].orientation = glm::normalize(_LeftHandOrientationAverage.getAverage());
|
||||
} else {
|
||||
_joints[j].orientation = jointOrientation;
|
||||
}
|
||||
|
@ -643,4 +654,4 @@ void KinectPlugin::InputDevice::clearState() {
|
|||
int poseIndex = KinectJointIndexToPoseIndex((KinectJointIndex)i);
|
||||
_poseStateMap[poseIndex] = controller::Pose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
// Kinect Header files
|
||||
#include <Kinect.h>
|
||||
#include <SimpleMovingAverage.h>
|
||||
|
||||
// Safe release for interfaces
|
||||
template<class Interface> inline void SafeRelease(Interface *& pInterfaceToRelease) {
|
||||
|
@ -58,6 +59,11 @@ public:
|
|||
virtual void saveSettings() const override;
|
||||
virtual void loadSettings() override;
|
||||
|
||||
private:
|
||||
// add variables for moving average
|
||||
ThreadSafeMovingAverage<glm::quat, 2> _LeftHandOrientationAverage;
|
||||
ThreadSafeMovingAverage<glm::quat, 2> _RightHandOrientationAverage;
|
||||
|
||||
protected:
|
||||
|
||||
struct KinectJoint {
|
||||
|
|
|
@ -29,13 +29,13 @@ var COLORS_TELEPORT_SEAT = {
|
|||
red: 255,
|
||||
green: 0,
|
||||
blue: 170
|
||||
}
|
||||
};
|
||||
|
||||
var COLORS_TELEPORT_CAN_TELEPORT = {
|
||||
red: 97,
|
||||
green: 247,
|
||||
blue: 255
|
||||
}
|
||||
};
|
||||
|
||||
var COLORS_TELEPORT_CANNOT_TELEPORT = {
|
||||
red: 0,
|
||||
|
@ -52,7 +52,7 @@ var COLORS_TELEPORT_CANCEL = {
|
|||
var TELEPORT_CANCEL_RANGE = 1;
|
||||
var COOL_IN_DURATION = 500;
|
||||
|
||||
const handInfo = {
|
||||
var handInfo = {
|
||||
right: {
|
||||
controllerInput: Controller.Standard.RightHand
|
||||
},
|
||||
|
@ -80,7 +80,7 @@ function Trigger(hand) {
|
|||
|
||||
this.down = function() {
|
||||
var down = _this.buttonValue === 1 ? 1.0 : 0.0;
|
||||
return down
|
||||
return down;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -90,8 +90,9 @@ var ignoredEntities = [];
|
|||
var TELEPORTER_STATES = {
|
||||
IDLE: 'idle',
|
||||
COOL_IN: 'cool_in',
|
||||
TARGETTING: 'targetting',
|
||||
TARGETTING_INVALID: 'targetting_invalid',
|
||||
}
|
||||
};
|
||||
|
||||
var TARGET = {
|
||||
NONE: 'none', // Not currently targetting anything
|
||||
|
@ -99,7 +100,7 @@ var TARGET = {
|
|||
INVALID: 'invalid', // The current target is invalid (wall, ceiling, etc.)
|
||||
SURFACE: 'surface', // The current target is a valid surface
|
||||
SEAT: 'seat', // The current target is a seat
|
||||
}
|
||||
};
|
||||
|
||||
function Teleporter() {
|
||||
var _this = this;
|
||||
|
@ -114,8 +115,8 @@ function Teleporter() {
|
|||
this.updateConnected = null;
|
||||
this.activeHand = null;
|
||||
|
||||
this.telporterMappingInternalName = 'Hifi-Teleporter-Internal-Dev-' + Math.random();
|
||||
this.teleportMappingInternal = Controller.newMapping(this.telporterMappingInternalName);
|
||||
this.teleporterMappingInternalName = 'Hifi-Teleporter-Internal-Dev-' + Math.random();
|
||||
this.teleportMappingInternal = Controller.newMapping(this.teleporterMappingInternalName);
|
||||
|
||||
// Setup overlays
|
||||
this.cancelOverlay = Overlays.addOverlay("model", {
|
||||
|
@ -135,11 +136,11 @@ function Teleporter() {
|
|||
});
|
||||
|
||||
this.enableMappings = function() {
|
||||
Controller.enableMapping(this.telporterMappingInternalName);
|
||||
Controller.enableMapping(this.teleporterMappingInternalName);
|
||||
};
|
||||
|
||||
this.disableMappings = function() {
|
||||
Controller.disableMapping(teleporter.telporterMappingInternalName);
|
||||
Controller.disableMapping(teleporter.teleporterMappingInternalName);
|
||||
};
|
||||
|
||||
this.cleanup = function() {
|
||||
|
@ -179,7 +180,7 @@ function Teleporter() {
|
|||
if (_this.state === TELEPORTER_STATES.COOL_IN) {
|
||||
_this.state = TELEPORTER_STATES.TARGETTING;
|
||||
}
|
||||
}, COOL_IN_DURATION)
|
||||
}, COOL_IN_DURATION);
|
||||
|
||||
this.activeHand = hand;
|
||||
this.enableMappings();
|
||||
|
@ -203,13 +204,13 @@ function Teleporter() {
|
|||
};
|
||||
|
||||
this.deleteOverlayBeams = function() {
|
||||
for (key in this.overlayLines) {
|
||||
for (var key in this.overlayLines) {
|
||||
if (this.overlayLines[key] !== null) {
|
||||
Overlays.deleteOverlay(this.overlayLines[key]);
|
||||
this.overlayLines[key] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.update = function() {
|
||||
if (_this.state === TELEPORTER_STATES.IDLE) {
|
||||
|
@ -272,7 +273,8 @@ function Teleporter() {
|
|||
this.hideCancelOverlay();
|
||||
this.hideSeatOverlay();
|
||||
|
||||
this.updateLineOverlay(_this.activeHand, pickRay.origin, intersection.intersection, COLORS_TELEPORT_CAN_TELEPORT);
|
||||
this.updateLineOverlay(_this.activeHand, pickRay.origin, intersection.intersection,
|
||||
COLORS_TELEPORT_CAN_TELEPORT);
|
||||
this.updateDestinationOverlay(this.targetOverlay, intersection);
|
||||
}
|
||||
} else if (teleportLocationType === TARGET.SEAT) {
|
||||
|
@ -284,13 +286,15 @@ function Teleporter() {
|
|||
}
|
||||
|
||||
|
||||
if (((_this.activeHand == 'left' ? leftPad : rightPad).buttonValue === 0) && inTeleportMode === true) {
|
||||
if (((_this.activeHand === 'left' ? leftPad : rightPad).buttonValue === 0) && inTeleportMode === true) {
|
||||
// remember the state before we exit teleport mode and set it back to IDLE
|
||||
var previousState = this.state;
|
||||
this.exitTeleportMode();
|
||||
this.hideCancelOverlay();
|
||||
this.hideTargetOverlay();
|
||||
this.hideSeatOverlay();
|
||||
|
||||
if (teleportLocationType === TARGET.NONE || teleportLocationType === TARGET.INVALID || this.state === TELEPORTER_STATES.COOL_IN) {
|
||||
if (teleportLocationType === TARGET.NONE || teleportLocationType === TARGET.INVALID || previousState === TELEPORTER_STATES.COOL_IN) {
|
||||
// Do nothing
|
||||
} else if (teleportLocationType === TARGET.SEAT) {
|
||||
Entities.callEntityMethod(intersection.entityID, 'sit');
|
||||
|
@ -321,7 +325,7 @@ function Teleporter() {
|
|||
this.overlayLines[hand] = Overlays.addOverlay("line3d", lineProperties);
|
||||
|
||||
} else {
|
||||
var success = Overlays.editOverlay(this.overlayLines[hand], {
|
||||
Overlays.editOverlay(this.overlayLines[hand], {
|
||||
start: closePoint,
|
||||
end: farPoint,
|
||||
color: color
|
||||
|
@ -361,7 +365,7 @@ function Teleporter() {
|
|||
};
|
||||
}
|
||||
|
||||
//related to repositioning the avatar after you teleport
|
||||
// related to repositioning the avatar after you teleport
|
||||
function getAvatarFootOffset() {
|
||||
var data = getJointData();
|
||||
var upperLeg, lowerLeg, foot, toe, toeTop;
|
||||
|
@ -384,14 +388,14 @@ function getAvatarFootOffset() {
|
|||
var offset = upperLeg + lowerLeg + foot + toe + toeTop;
|
||||
offset = offset / 100;
|
||||
return offset;
|
||||
};
|
||||
}
|
||||
|
||||
function getJointData() {
|
||||
var allJointData = [];
|
||||
var jointNames = MyAvatar.jointNames;
|
||||
jointNames.forEach(function(joint, index) {
|
||||
var translation = MyAvatar.getJointTranslation(index);
|
||||
var rotation = MyAvatar.getJointRotation(index)
|
||||
var rotation = MyAvatar.getJointRotation(index);
|
||||
allJointData.push({
|
||||
joint: joint,
|
||||
index: index,
|
||||
|
@ -401,7 +405,7 @@ function getJointData() {
|
|||
});
|
||||
|
||||
return allJointData;
|
||||
};
|
||||
}
|
||||
|
||||
var leftPad = new ThumbPad('left');
|
||||
var rightPad = new ThumbPad('right');
|
||||
|
@ -420,7 +424,7 @@ function isMoving() {
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function parseJSON(json) {
|
||||
try {
|
||||
|
@ -433,7 +437,7 @@ function parseJSON(json) {
|
|||
// point that is being intersected with is looked at. If this normal is more
|
||||
// than MAX_ANGLE_FROM_UP_TO_TELEPORT degrees from <0, 1, 0> (straight up), then
|
||||
// you can't teleport there.
|
||||
const MAX_ANGLE_FROM_UP_TO_TELEPORT = 70;
|
||||
var MAX_ANGLE_FROM_UP_TO_TELEPORT = 70;
|
||||
function getTeleportTargetType(intersection) {
|
||||
if (!intersection.intersects) {
|
||||
return TARGET.NONE;
|
||||
|
@ -465,7 +469,7 @@ function getTeleportTargetType(intersection) {
|
|||
} else {
|
||||
return TARGET.SURFACE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function registerMappings() {
|
||||
mappingName = 'Hifi-Teleporter-Dev-' + Math.random();
|
||||
|
@ -487,7 +491,7 @@ function registerMappings() {
|
|||
if (isMoving() === true) {
|
||||
return;
|
||||
}
|
||||
teleporter.enterTeleportMode('left')
|
||||
teleporter.enterTeleportMode('left');
|
||||
return;
|
||||
});
|
||||
teleportMapping.from(Controller.Standard.RightPrimaryThumb)
|
||||
|
@ -502,10 +506,10 @@ function registerMappings() {
|
|||
return;
|
||||
}
|
||||
|
||||
teleporter.enterTeleportMode('right')
|
||||
teleporter.enterTeleportMode('right');
|
||||
return;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
registerMappings();
|
||||
|
||||
|
@ -521,7 +525,6 @@ Script.scriptEnding.connect(cleanup);
|
|||
|
||||
var isDisabled = false;
|
||||
var handleTeleportMessages = function(channel, message, sender) {
|
||||
var data;
|
||||
if (sender === MyAvatar.sessionUUID) {
|
||||
if (channel === 'Hifi-Teleport-Disabler') {
|
||||
if (message === 'both') {
|
||||
|
@ -531,7 +534,7 @@ var handleTeleportMessages = function(channel, message, sender) {
|
|||
isDisabled = 'left';
|
||||
}
|
||||
if (message === 'right') {
|
||||
isDisabled = 'right'
|
||||
isDisabled = 'right';
|
||||
}
|
||||
if (message === 'none') {
|
||||
isDisabled = false;
|
||||
|
@ -545,7 +548,7 @@ var handleTeleportMessages = function(channel, message, sender) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Messages.subscribe('Hifi-Teleport-Disabler');
|
||||
Messages.subscribe('Hifi-Teleport-Ignore-Add');
|
||||
|
|
|
@ -21,6 +21,7 @@ function addImage(data) {
|
|||
img = document.createElement("IMG"),
|
||||
div2 = document.createElement("DIV"),
|
||||
id = "p" + idCounter++;
|
||||
img.id = id + "img";
|
||||
function toggle() { data.share = input.checked; }
|
||||
div.style.height = "" + Math.floor(100 / imageCount) + "%";
|
||||
if (imageCount > 1) {
|
||||
|
@ -33,7 +34,7 @@ function addImage(data) {
|
|||
label.setAttribute('for', id); // cannot do label.for =
|
||||
input.id = id;
|
||||
input.type = "checkbox";
|
||||
input.checked = (id === "p0");
|
||||
input.checked = false;
|
||||
data.share = input.checked;
|
||||
input.addEventListener('change', toggle);
|
||||
div2.setAttribute("class", "property checkbox");
|
||||
|
@ -46,9 +47,9 @@ function addImage(data) {
|
|||
document.getElementById("snapshot-images").appendChild(div);
|
||||
paths.push(data);
|
||||
}
|
||||
function handleShareButtons(shareMsg) {
|
||||
function handleShareButtons(messageOptions) {
|
||||
var openFeed = document.getElementById('openFeed');
|
||||
openFeed.checked = shareMsg.openFeedAfterShare;
|
||||
openFeed.checked = messageOptions.openFeedAfterShare;
|
||||
openFeed.onchange = function () {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "snapshot",
|
||||
|
@ -56,7 +57,7 @@ function handleShareButtons(shareMsg) {
|
|||
}));
|
||||
};
|
||||
|
||||
if (!shareMsg.canShare) {
|
||||
if (!messageOptions.canShare) {
|
||||
// this means you may or may not be logged in, but can't share
|
||||
// because you are not in a public place.
|
||||
document.getElementById("sharing").innerHTML = "<p class='prompt'>Snapshots can be shared when they're taken in shareable places.";
|
||||
|
@ -74,13 +75,26 @@ window.onload = function () {
|
|||
return;
|
||||
}
|
||||
|
||||
// last element of list contains a bool for whether or not we can share stuff
|
||||
var shareMsg = message.action.pop();
|
||||
handleShareButtons(shareMsg);
|
||||
|
||||
// rest are image paths which we add
|
||||
imageCount = message.action.length;
|
||||
message.action.forEach(addImage);
|
||||
// The last element of the message contents list contains a bunch of options,
|
||||
// including whether or not we can share stuff
|
||||
// The other elements of the list contain image paths.
|
||||
var messageOptions = message.action.pop();
|
||||
handleShareButtons(messageOptions);
|
||||
|
||||
if (messageOptions.containsGif) {
|
||||
if (messageOptions.processingGif) {
|
||||
imageCount = message.action.length + 1; // "+1" for the GIF that'll finish processing soon
|
||||
message.action.unshift({ localPath: '../../../resources/icons/loadingDark.gif' });
|
||||
message.action.forEach(addImage);
|
||||
document.getElementById('p0').disabled = true;
|
||||
} else {
|
||||
document.getElementById('p0').disabled = false;
|
||||
document.getElementById('p0img').src = message.action[0].localPath;
|
||||
}
|
||||
} else {
|
||||
imageCount = message.action.length;
|
||||
message.action.forEach(addImage);
|
||||
}
|
||||
});
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "snapshot",
|
||||
|
|
|
@ -511,7 +511,6 @@ WebTablet.prototype.mousePressEvent = function (event) {
|
|||
tablet.gotoHomeScreen();
|
||||
this.setHomeButtonTexture();
|
||||
}
|
||||
Messages.sendLocalMessage("home", this.homeButtonID);
|
||||
}
|
||||
} else if (!HMD.active && (!overlayPickResults.intersects || overlayPickResults.overlayID !== this.webOverlayID)) {
|
||||
this.dragging = true;
|
||||
|
|
|
@ -532,7 +532,7 @@ function onNotify(msg) {
|
|||
createNotification(wordWrap(msg), NotificationType.UNKNOWN); // Needs a generic notification system for user feedback, thus using this
|
||||
}
|
||||
|
||||
function onSnapshotTaken(pathStillSnapshot, pathAnimatedSnapshot, notify) {
|
||||
function onSnapshotTaken(pathStillSnapshot, notify) {
|
||||
if (notify) {
|
||||
var imageProperties = {
|
||||
path: "file:///" + pathStillSnapshot,
|
||||
|
@ -656,8 +656,8 @@ Script.update.connect(update);
|
|||
Script.scriptEnding.connect(scriptEnding);
|
||||
Menu.menuItemEvent.connect(menuItemEvent);
|
||||
Window.domainConnectionRefused.connect(onDomainConnectionRefused);
|
||||
Window.snapshotTaken.connect(onSnapshotTaken);
|
||||
Window.processingGif.connect(processingGif);
|
||||
Window.stillSnapshotTaken.connect(onSnapshotTaken);
|
||||
Window.processingGifStarted.connect(processingGif);
|
||||
Window.connectionAdded.connect(connectionAdded);
|
||||
Window.connectionError.connect(connectionError);
|
||||
Window.notifyEditError = onEditError;
|
||||
|
|
|
@ -35,15 +35,17 @@ function shouldOpenFeedAfterShare() {
|
|||
function showFeedWindow() {
|
||||
if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar"))
|
||||
|| (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar"))) {
|
||||
DialogsManager.showFeed();
|
||||
} else {
|
||||
tablet.loadQMLSource("TabletAddressDialog.qml");
|
||||
} else {
|
||||
tablet.initialScreen("TabletAddressDialog.qml");
|
||||
HMD.openTablet();
|
||||
}
|
||||
}
|
||||
|
||||
var outstanding;
|
||||
var readyData;
|
||||
var shareAfterLogin = false;
|
||||
var snapshotToShareAfterLogin;
|
||||
function onMessage(message) {
|
||||
// Receives message from the html dialog via the qwebchannel EventBridge. This is complicated by the following:
|
||||
// 1. Although we can send POJOs, we cannot receive a toplevel object. (Arrays of POJOs are fine, though.)
|
||||
|
@ -70,7 +72,7 @@ function onMessage(message) {
|
|||
|| (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar"))) {
|
||||
Desktop.show("hifi/dialogs/GeneralPreferencesDialog.qml", "General Preferences");
|
||||
} else {
|
||||
tablet.loadQMLSource("TabletGeneralPreferences.qml");
|
||||
tablet.loadQMLOnTop("TabletGeneralPreferences.qml");
|
||||
}
|
||||
break;
|
||||
case 'setOpenFeedFalse':
|
||||
|
@ -82,26 +84,39 @@ function onMessage(message) {
|
|||
default:
|
||||
//tablet.webEventReceived.disconnect(onMessage); // <<< It's probably this that's missing?!
|
||||
HMD.closeTablet();
|
||||
tablet.gotoHomeScreen();
|
||||
isLoggedIn = Account.isLoggedIn();
|
||||
message.action.forEach(function (submessage) {
|
||||
if (submessage.share && !isLoggedIn) {
|
||||
needsLogin = true;
|
||||
submessage.share = false;
|
||||
shareAfterLogin = true;
|
||||
snapshotToShareAfterLogin = {path: submessage.localPath, href: submessage.href};
|
||||
}
|
||||
if (submessage.share) {
|
||||
print('sharing', submessage.localPath);
|
||||
outstanding++;
|
||||
outstanding = true;
|
||||
Window.shareSnapshot(submessage.localPath, submessage.href);
|
||||
} else {
|
||||
print('not sharing', submessage.localPath);
|
||||
}
|
||||
|
||||
});
|
||||
if (!outstanding && shouldOpenFeedAfterShare()) {
|
||||
//showFeedWindow();
|
||||
if (outstanding && shouldOpenFeedAfterShare()) {
|
||||
showFeedWindow();
|
||||
outstanding = false;
|
||||
}
|
||||
if (needsLogin) { // after the possible feed, so that the login is on top
|
||||
Account.checkAndSignalForAccessToken();
|
||||
var isLoggedIn = Account.isLoggedIn();
|
||||
|
||||
if (!isLoggedIn) {
|
||||
if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar"))
|
||||
|| (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar"))) {
|
||||
Menu.triggerOption("Login / Sign Up");
|
||||
} else {
|
||||
tablet.loadQMLOnTop("../../dialogs/TabletLoginDialog.qml");
|
||||
HMD.openTablet();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +157,9 @@ function onClicked() {
|
|||
resetOverlays = Menu.isOptionChecked("Overlays"); // For completness. Certainly true if the button is visible to be clicke.
|
||||
reticleVisible = Reticle.visible;
|
||||
Reticle.visible = false;
|
||||
Window.snapshotTaken.connect(resetButtons);
|
||||
Window.stillSnapshotTaken.connect(stillSnapshotTaken);
|
||||
Window.processingGifStarted.connect(processingGifStarted);
|
||||
Window.processingGifCompleted.connect(processingGifCompleted);
|
||||
|
||||
// hide overlays if they are on
|
||||
if (resetOverlays) {
|
||||
|
@ -178,25 +195,14 @@ function isDomainOpen(id) {
|
|||
response.total_entries;
|
||||
}
|
||||
|
||||
function resetButtons(pathStillSnapshot, pathAnimatedSnapshot, notify) {
|
||||
// If we're not taking an animated snapshot, we have to show the HUD.
|
||||
// If we ARE taking an animated snapshot, we've already re-enabled the HUD by this point.
|
||||
if (pathAnimatedSnapshot === "") {
|
||||
// show hud
|
||||
|
||||
Reticle.visible = reticleVisible;
|
||||
// show overlays if they were on
|
||||
if (resetOverlays) {
|
||||
Menu.setIsOptionChecked("Overlays", true);
|
||||
}
|
||||
} else {
|
||||
// Allow the user to click the snapshot HUD button again
|
||||
if (!buttonConnected) {
|
||||
button.clicked.connect(onClicked);
|
||||
buttonConnected = true;
|
||||
}
|
||||
function stillSnapshotTaken(pathStillSnapshot, notify) {
|
||||
// show hud
|
||||
Reticle.visible = reticleVisible;
|
||||
// show overlays if they were on
|
||||
if (resetOverlays) {
|
||||
Menu.setIsOptionChecked("Overlays", true);
|
||||
}
|
||||
Window.snapshotTaken.disconnect(resetButtons);
|
||||
Window.stillSnapshotTaken.disconnect(stillSnapshotTaken);
|
||||
|
||||
// A Snapshot Review dialog might be left open indefinitely after taking the picture,
|
||||
// during which time the user may have moved. So stash that info in the dialog so that
|
||||
|
@ -205,12 +211,11 @@ function resetButtons(pathStillSnapshot, pathAnimatedSnapshot, notify) {
|
|||
var confirmShareContents = [
|
||||
{ localPath: pathStillSnapshot, href: href },
|
||||
{
|
||||
containsGif: false,
|
||||
processingGif: false,
|
||||
canShare: !!isDomainOpen(domainId),
|
||||
openFeedAfterShare: shouldOpenFeedAfterShare()
|
||||
}];
|
||||
if (pathAnimatedSnapshot !== "") {
|
||||
confirmShareContents.unshift({ localPath: pathAnimatedSnapshot, href: href });
|
||||
}
|
||||
confirmShare(confirmShareContents);
|
||||
if (clearOverlayWhenMoving) {
|
||||
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
||||
|
@ -218,15 +223,51 @@ function resetButtons(pathStillSnapshot, pathAnimatedSnapshot, notify) {
|
|||
HMD.openTablet();
|
||||
}
|
||||
|
||||
function processingGif() {
|
||||
// show hud
|
||||
Reticle.visible = reticleVisible;
|
||||
function processingGifStarted(pathStillSnapshot) {
|
||||
Window.processingGifStarted.disconnect(processingGifStarted);
|
||||
button.clicked.disconnect(onClicked);
|
||||
buttonConnected = false;
|
||||
// show hud
|
||||
Reticle.visible = reticleVisible;
|
||||
// show overlays if they were on
|
||||
if (resetOverlays) {
|
||||
Menu.setIsOptionChecked("Overlays", true);
|
||||
}
|
||||
|
||||
var confirmShareContents = [
|
||||
{ localPath: pathStillSnapshot, href: href },
|
||||
{
|
||||
containsGif: true,
|
||||
processingGif: true,
|
||||
canShare: !!isDomainOpen(domainId),
|
||||
openFeedAfterShare: shouldOpenFeedAfterShare()
|
||||
}];
|
||||
confirmShare(confirmShareContents);
|
||||
if (clearOverlayWhenMoving) {
|
||||
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
||||
}
|
||||
HMD.openTablet();
|
||||
}
|
||||
|
||||
function processingGifCompleted(pathAnimatedSnapshot) {
|
||||
Window.processingGifCompleted.disconnect(processingGifCompleted);
|
||||
button.clicked.connect(onClicked);
|
||||
buttonConnected = true;
|
||||
|
||||
var confirmShareContents = [
|
||||
{ localPath: pathAnimatedSnapshot, href: href },
|
||||
{
|
||||
containsGif: true,
|
||||
processingGif: false,
|
||||
canShare: !!isDomainOpen(domainId),
|
||||
openFeedAfterShare: shouldOpenFeedAfterShare()
|
||||
}];
|
||||
readyData = confirmShareContents;
|
||||
|
||||
tablet.emitScriptEvent(JSON.stringify({
|
||||
type: "snapshot",
|
||||
action: readyData
|
||||
}));
|
||||
}
|
||||
|
||||
function onTabletScreenChanged(type, url) {
|
||||
|
@ -235,13 +276,23 @@ function onTabletScreenChanged(type, url) {
|
|||
isInSnapshotReview = false;
|
||||
}
|
||||
}
|
||||
function onConnected() {
|
||||
if (shareAfterLogin && Account.isLoggedIn()) {
|
||||
print('sharing', snapshotToShareAfterLogin.path);
|
||||
Window.shareSnapshot(snapshotToShareAfterLogin.path, snapshotToShareAfterLogin.href);
|
||||
shareAfterLogin = false;
|
||||
if (shouldOpenFeedAfterShare()) {
|
||||
showFeedWindow();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
button.clicked.connect(onClicked);
|
||||
buttonConnected = true;
|
||||
Window.snapshotShared.connect(snapshotShared);
|
||||
Window.processingGif.connect(processingGif);
|
||||
tablet.screenChanged.connect(onTabletScreenChanged);
|
||||
|
||||
Account.usernameChanged.connect(onConnected);
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (buttonConnected) {
|
||||
button.clicked.disconnect(onClicked);
|
||||
|
@ -251,7 +302,6 @@ Script.scriptEnding.connect(function () {
|
|||
tablet.removeButton(button);
|
||||
}
|
||||
Window.snapshotShared.disconnect(snapshotShared);
|
||||
Window.processingGif.disconnect(processingGif);
|
||||
tablet.screenChanged.disconnect(onTabletScreenChanged);
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue