mirror of
https://github.com/lubosz/overte.git
synced 2025-04-14 14:46:55 +02:00
Merge pull request #16305 from highfidelity/master
Merge master into instancing
This commit is contained in:
commit
2fcb526a5c
33 changed files with 918 additions and 230 deletions
|
@ -556,7 +556,51 @@ void EntityScriptServer::checkAndCallPreload(const EntityItemID& entityID, bool
|
|||
}
|
||||
|
||||
void EntityScriptServer::sendStatsPacket() {
|
||||
QJsonObject statsObject;
|
||||
|
||||
QJsonObject octreeStats;
|
||||
octreeStats["elementCount"] = (double)OctreeElement::getNodeCount();
|
||||
octreeStats["internalElementCount"] = (double)OctreeElement::getInternalNodeCount();
|
||||
octreeStats["leafElementCount"] = (double)OctreeElement::getLeafNodeCount();
|
||||
statsObject["octree_stats"] = octreeStats;
|
||||
|
||||
QJsonObject scriptEngineStats;
|
||||
int numberRunningScripts = 0;
|
||||
const auto scriptEngine = _entitiesScriptEngine;
|
||||
if (scriptEngine) {
|
||||
numberRunningScripts = scriptEngine->getNumRunningEntityScripts();
|
||||
}
|
||||
scriptEngineStats["number_running_scripts"] = numberRunningScripts;
|
||||
statsObject["script_engine_stats"] = scriptEngineStats;
|
||||
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
QJsonObject nodesObject;
|
||||
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||
QJsonObject clientStats;
|
||||
const QString uuidString(uuidStringWithoutCurlyBraces(node->getUUID()));
|
||||
clientStats["node_type"] = NodeType::getNodeTypeName(node->getType());
|
||||
auto& nodeStats = node->getConnectionStats();
|
||||
|
||||
static const QString NODE_OUTBOUND_KBPS_STAT_KEY("outbound_kbit/s");
|
||||
static const QString NODE_INBOUND_KBPS_STAT_KEY("inbound_kbit/s");
|
||||
|
||||
// add the key to ask the domain-server for a username replacement, if it has it
|
||||
clientStats[USERNAME_UUID_REPLACEMENT_STATS_KEY] = uuidString;
|
||||
|
||||
clientStats[NODE_OUTBOUND_KBPS_STAT_KEY] = node->getOutboundKbps();
|
||||
clientStats[NODE_INBOUND_KBPS_STAT_KEY] = node->getInboundKbps();
|
||||
|
||||
using namespace std::chrono;
|
||||
const float statsPeriod = duration<float, seconds::period>(nodeStats.endTime - nodeStats.startTime).count();
|
||||
clientStats["unreliable_packet/s"] = (nodeStats.sentUnreliablePackets + nodeStats.receivedUnreliablePackets) / statsPeriod;
|
||||
clientStats["reliable_packet/s"] = (nodeStats.sentPackets + nodeStats.receivedPackets) / statsPeriod;
|
||||
|
||||
nodesObject[uuidString] = clientStats;
|
||||
});
|
||||
|
||||
statsObject["nodes"] = nodesObject;
|
||||
addPacketStatsAndSendStatsPacket(statsObject);
|
||||
}
|
||||
|
||||
void EntityScriptServer::handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
|
|
|
@ -136,6 +136,23 @@ function getCurrentDomainIDType() {
|
|||
return DOMAIN_ID_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
function isCloudDomain() {
|
||||
|
||||
if (!domainIDIsSet()) {
|
||||
return false;
|
||||
}
|
||||
if (typeof DomainInfo === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
if (DomainInfo === null) {
|
||||
return false;
|
||||
}
|
||||
if (typeof DomainInfo.cloud_domain !== "boolean") {
|
||||
return false;
|
||||
}
|
||||
return DomainInfo.cloud_domain;
|
||||
}
|
||||
|
||||
function showLoadingDialog(msg) {
|
||||
var message = '<div class="text-center">';
|
||||
message += '<span class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span> ' + msg;
|
||||
|
|
|
@ -606,6 +606,9 @@ $(document).ready(function(){
|
|||
var address = DomainInfo.network_address === null ? '' : DomainInfo.network_address;
|
||||
var port = DomainInfo.network_port === null ? '' : DomainInfo.network_port;
|
||||
var modal_body = "<div class='form-group'>";
|
||||
if (isCloudDomain()) {
|
||||
modal_body += '<div style="color:red;font-weight: bold">Changing the network settings may actually break your domain.</div>';
|
||||
}
|
||||
if (includeAddress) {
|
||||
modal_body += "<label class='control-label'>Address</label>";
|
||||
modal_body += "<input type='text' id='network-address-input' class='form-control' value='" + address + "'>";
|
||||
|
@ -867,6 +870,10 @@ $(document).ready(function(){
|
|||
}
|
||||
}
|
||||
|
||||
if (getCurrentDomainIDType() === DOMAIN_ID_TYPE_TEMP) {
|
||||
$(Settings.DOMAIN_ID_SELECTOR).siblings('span').append(" <b>This is a temporary domain and will not be visible in your domain list.</b>");
|
||||
}
|
||||
|
||||
if (accessTokenIsSet()) {
|
||||
appendAddButtonToPlacesTable();
|
||||
}
|
||||
|
|
|
@ -385,7 +385,7 @@ void DomainServer::parseCommandLine(int argc, char* argv[]) {
|
|||
}
|
||||
|
||||
if (_iceServerAddr.isEmpty()) {
|
||||
qCWarning(domain_server_ice) << "Could not parse an IP address and port combination from" << hostnamePortString;
|
||||
qCWarning(domain_server_ice) << "ALERT: Could not parse an IP address and port combination from" << hostnamePortString;
|
||||
::exit(0);
|
||||
}
|
||||
}
|
||||
|
@ -876,7 +876,7 @@ void DomainServer::setupAutomaticNetworking() {
|
|||
nodeList->startSTUNPublicSocketUpdate();
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Cannot enable domain-server automatic networking without a domain ID."
|
||||
qCCritical(domain_server) << "PAGE: Cannot enable domain-server automatic networking without a domain ID."
|
||||
<< "Please add an ID to your config file or via the web interface.";
|
||||
return;
|
||||
}
|
||||
|
@ -1635,8 +1635,9 @@ void DomainServer::handleFailedICEServerAddressUpdate(QNetworkReply* requestRepl
|
|||
} else {
|
||||
const int ICE_SERVER_UPDATE_RETRY_MS = 2 * 1000;
|
||||
|
||||
qCWarning(domain_server_ice) << "Failed to update ice-server address (" << _iceServerSocket << ") with High Fidelity Metaverse - error was"
|
||||
<< requestReply->errorString();
|
||||
qCWarning(domain_server_ice) << "PAGE: Failed to update ice-server address (" << _iceServerSocket <<
|
||||
") with Metaverse (" << requestReply->url() << ") (critical error for auto-networking) error:" <<
|
||||
requestReply->errorString();
|
||||
qCWarning(domain_server_ice) << "\tRe-attempting in" << ICE_SERVER_UPDATE_RETRY_MS / 1000 << "seconds";
|
||||
|
||||
QTimer::singleShot(ICE_SERVER_UPDATE_RETRY_MS, this, SLOT(sendICEServerAddressToMetaverseAPI()));
|
||||
|
@ -3450,8 +3451,9 @@ void DomainServer::randomizeICEServerAddress(bool shouldTriggerHostLookup) {
|
|||
// we ended up with an empty list since everything we've tried has failed
|
||||
// so clear the set of failed addresses and start going through them again
|
||||
|
||||
qCWarning(domain_server_ice) << "All current ice-server addresses have failed - re-attempting all current addresses for"
|
||||
<< _iceServerAddr;
|
||||
qCWarning(domain_server_ice) <<
|
||||
"PAGE: All current ice-server addresses have failed - re-attempting all current addresses for"
|
||||
<< _iceServerAddr;
|
||||
|
||||
_failedIceServerAddresses.clear();
|
||||
candidateICEAddresses = _iceServerAddresses;
|
||||
|
|
Binary file not shown.
BIN
interface/resources/avatar/animations/sitting_idle04.fbx
Normal file
BIN
interface/resources/avatar/animations/sitting_idle04.fbx
Normal file
Binary file not shown.
BIN
interface/resources/avatar/animations/sitting_idle05.fbx
Normal file
BIN
interface/resources/avatar/animations/sitting_idle05.fbx
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -640,8 +640,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedTalk02",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpDuration": 30,
|
||||
"interpTarget": 30,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": true,
|
||||
|
@ -651,8 +651,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedTalk03",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpDuration": 30,
|
||||
"interpTarget": 30,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": true,
|
||||
|
@ -662,8 +662,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedTalk04",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpDuration": 30,
|
||||
"interpTarget": 30,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": true,
|
||||
|
@ -680,84 +680,414 @@
|
|||
"children": [
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 800,
|
||||
"loopFlag": true,
|
||||
"startFrame": 0,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle.fbx"
|
||||
},
|
||||
"id": "seatedIdle01",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 800,
|
||||
"loopFlag": true,
|
||||
"startFrame": 1,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle02.fbx"
|
||||
},
|
||||
"id": "seatedIdle02",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 800,
|
||||
"loopFlag": true,
|
||||
"startFrame": 0,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle03.fbx"
|
||||
},
|
||||
"id": "seatedIdle03",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 800,
|
||||
"loopFlag": true,
|
||||
"startFrame": 1,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle04.fbx"
|
||||
},
|
||||
"id": "seatedIdle04",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 332,
|
||||
"loopFlag": true,
|
||||
"startFrame": 1,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle05.fbx"
|
||||
},
|
||||
"id": "seatedIdle05",
|
||||
"type": "clip"
|
||||
}
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 800,
|
||||
"loopFlag": true,
|
||||
"startFrame": 0,
|
||||
"currentState": "seatedIdle01",
|
||||
"endFrame": 30,
|
||||
"randomSwitchTimeMax": 40,
|
||||
"randomSwitchTimeMin": 10,
|
||||
"startFrame": 10,
|
||||
"states": [
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedIdle01",
|
||||
"interpDuration": 30,
|
||||
"interpTarget": 30,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": true,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedIdle02",
|
||||
"interpDuration": 30,
|
||||
"interpTarget": 30,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": true,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedIdle03",
|
||||
"interpDuration": 30,
|
||||
"interpTarget": 30,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": true,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedIdle04",
|
||||
"interpDuration": 30,
|
||||
"interpTarget": 30,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": true,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedIdle05",
|
||||
"interpDuration": 30,
|
||||
"interpTarget": 30,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": true,
|
||||
"transitions": [
|
||||
]
|
||||
}
|
||||
],
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle.fbx"
|
||||
"triggerRandomSwitch": "seatedIdleSwitch",
|
||||
"triggerTimeMax": 10
|
||||
},
|
||||
"id": "seatedIdle01",
|
||||
"type": "clip"
|
||||
"id": "masterSeatedIdle",
|
||||
"type": "randomSwitchStateMachine"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 744,
|
||||
"loopFlag": false,
|
||||
"startFrame": 1,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle_once_shifting.fbx"
|
||||
},
|
||||
"id": "seatedFidgetShifting",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 420,
|
||||
"loopFlag": false,
|
||||
"startFrame": 1,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle_once_lookfidget.fbx"
|
||||
},
|
||||
"id": "seatedFidgetLookFidget",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 282,
|
||||
"loopFlag": false,
|
||||
"startFrame": 1,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle_once_shiftweight.fbx"
|
||||
},
|
||||
"id": "seatedFidgetShiftWeight",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 428,
|
||||
"loopFlag": false,
|
||||
"startFrame": 1,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle_once_fidget.fbx"
|
||||
},
|
||||
"id": "seatedFidgeting",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 324,
|
||||
"loopFlag": false,
|
||||
"startFrame": 1,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle_once_lookaround.fbx"
|
||||
},
|
||||
"id": "seatedFidgetLookAround",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 120,
|
||||
"loopFlag": false,
|
||||
"startFrame": 1,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle_once_lookleftright.fbx"
|
||||
},
|
||||
"id": "seatedFidgetLookLeftRight",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 178,
|
||||
"loopFlag": false,
|
||||
"startFrame": 1,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle_once_leanforward.fbx"
|
||||
},
|
||||
"id": "seatedFidgetLeanForward",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 140,
|
||||
"loopFlag": false,
|
||||
"startFrame": 1,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle_once_shakelegs.fbx"
|
||||
},
|
||||
"id": "seatedFidgetShakeLegs",
|
||||
"type": "clip"
|
||||
}
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 800,
|
||||
"loopFlag": true,
|
||||
"startFrame": 0,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle02.fbx"
|
||||
"currentState": "seatedFidgetShifting",
|
||||
"states": [
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedFidgetShifting",
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": false,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedFidgetLookFidget",
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": false,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedFidgetShiftWeight",
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": false,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedFidgeting",
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": false,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedFidgetLookAround",
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": false,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedFidgetLookLeftRight",
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": false,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedFidgetLeanForward",
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": false,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedFidgetShakeLegs",
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": false,
|
||||
"transitions": [
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "seatedIdle02",
|
||||
"type": "clip"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
],
|
||||
"data": {
|
||||
"endFrame": 800,
|
||||
"loopFlag": true,
|
||||
"startFrame": 0,
|
||||
"timeScale": 1,
|
||||
"url": "qrc:///avatar/animations/sitting_idle03.fbx"
|
||||
},
|
||||
"id": "seatedIdle03",
|
||||
"type": "clip"
|
||||
"id": "seatedFidget",
|
||||
"type": "randomSwitchStateMachine"
|
||||
}
|
||||
],
|
||||
"data": {
|
||||
"currentState": "seatedIdle01",
|
||||
"currentState": "masterSeatedIdle",
|
||||
"randomSwitchTimeMax": 20,
|
||||
"randomSwitchTimeMin": 10,
|
||||
"states": [
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedIdle01",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"id": "masterSeatedIdle",
|
||||
"interpDuration": 20,
|
||||
"interpTarget": 20,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": true,
|
||||
"resume": false,
|
||||
"transitions": [
|
||||
{
|
||||
"randomSwitchState": "seatedFidget",
|
||||
"var": "timeToSeatedFidget"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedIdle02",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"id": "seatedFidget",
|
||||
"interpDuration": 30,
|
||||
"interpTarget": 30,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": true,
|
||||
"transitions": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "seatedIdle03",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 1,
|
||||
"resume": true,
|
||||
"priority": -1,
|
||||
"resume": false,
|
||||
"transitions": [
|
||||
{
|
||||
"randomSwitchState": "masterSeatedIdle",
|
||||
"var": "seatedFidgetShiftingOnDone"
|
||||
},
|
||||
{
|
||||
"randomSwitchState": "masterSeatedIdle",
|
||||
"var": "seatedFidgetLookFidgetOnDone"
|
||||
},
|
||||
{
|
||||
"randomSwitchState": "masterSeatedIdle",
|
||||
"var": "seatedFidgetShiftWeightOnDone"
|
||||
},
|
||||
{
|
||||
"randomSwitchState": "masterSeatedIdle",
|
||||
"var": "seatedFidgetingOnDone"
|
||||
},
|
||||
{
|
||||
"randomSwitchState": "masterSeatedIdle",
|
||||
"var": "seatedFidgetLookAroundOnDone"
|
||||
},
|
||||
{
|
||||
"randomSwitchState": "masterSeatedIdle",
|
||||
"var": "seatedFidgetLookLeftRightOnDone"
|
||||
},
|
||||
{
|
||||
"randomSwitchState": "masterSeatedIdle",
|
||||
"var": "seatedFidgetLeanForwardOnDone"
|
||||
},
|
||||
{
|
||||
"randomSwitchState": "masterSeatedIdle",
|
||||
"var": "seatedFidgetShakeLegsOnDone"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"triggerRandomSwitch": "seatedIdleSwitch"
|
||||
"transitionVar": "timeToSeatedFidget",
|
||||
"triggerRandomSwitch": "",
|
||||
"triggerTimeMax": 45,
|
||||
"triggerTimeMin": 10
|
||||
},
|
||||
"id": "seatedIdle",
|
||||
"type": "randomSwitchStateMachine"
|
||||
|
@ -1544,9 +1874,9 @@
|
|||
"type": "randomSwitchStateMachine"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
"children": [
|
||||
{
|
||||
"children": [
|
||||
"children": [
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
|
@ -1653,7 +1983,7 @@
|
|||
"blendType": "addAbsolute"
|
||||
},
|
||||
"id": "seatedReactionPointBase",
|
||||
"type": "blendLinear"
|
||||
"type": "blendLinear"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
|
@ -2148,8 +2478,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "talk",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 0.33,
|
||||
"resume": true,
|
||||
|
@ -2159,8 +2489,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "talk02",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 0.33,
|
||||
"resume": true,
|
||||
|
@ -2170,8 +2500,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "talk03",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 0.33,
|
||||
"resume": true,
|
||||
|
@ -2181,8 +2511,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "talk04",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 0.33,
|
||||
"resume": true,
|
||||
|
@ -2192,8 +2522,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "talk_armsdown",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 0.33,
|
||||
"resume": true,
|
||||
|
@ -2203,8 +2533,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "talk_lefthand",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 0.33,
|
||||
"resume": true,
|
||||
|
@ -2214,8 +2544,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "talk_righthand",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpDuration": 1,
|
||||
"interpTarget": 1,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": 0.33,
|
||||
"resume": true,
|
||||
|
@ -2773,8 +3103,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "fidget",
|
||||
"interpDuration": 15,
|
||||
"interpTarget": 15,
|
||||
"interpDuration": 20,
|
||||
"interpTarget": 20,
|
||||
"interpType": "evaluateBoth",
|
||||
"priority": -1,
|
||||
"resume": false,
|
||||
|
@ -3997,8 +4327,8 @@
|
|||
{
|
||||
"easingType": "easeInOutQuad",
|
||||
"id": "idleTalkOverlay",
|
||||
"interpDuration": 20,
|
||||
"interpTarget": 20,
|
||||
"interpDuration": 25,
|
||||
"interpTarget": 25,
|
||||
"interpType": "evaluateBoth",
|
||||
"transitions": [
|
||||
{
|
||||
|
|
|
@ -3610,10 +3610,9 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
|
|||
mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
|
||||
_myCamera.setPosition(extractTranslation(camMat));
|
||||
_myCamera.setOrientation(glmExtractRotation(camMat));
|
||||
}
|
||||
else {
|
||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition());
|
||||
_myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation());
|
||||
} else {
|
||||
_myCamera.setPosition(myAvatar->getLookAtPivotPoint());
|
||||
_myCamera.setOrientation(myAvatar->getLookAtRotation());
|
||||
}
|
||||
} else if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {
|
||||
if (isHMDMode()) {
|
||||
|
@ -3647,9 +3646,9 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
|
|||
if (mode == CAMERA_MODE_SELFIE) {
|
||||
lookAtRotation = lookAtRotation * glm::angleAxis(PI, myAvatar->getWorldOrientation() * Vectors::UP);
|
||||
}
|
||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
||||
_myCamera.setPosition(myAvatar->getLookAtPivotPoint()
|
||||
+ lookAtRotation * boomOffset);
|
||||
_myCamera.lookAt(myAvatar->getDefaultEyePosition());
|
||||
_myCamera.lookAt(myAvatar->getLookAtPivotPoint());
|
||||
}
|
||||
}
|
||||
} else if (mode == CAMERA_MODE_MIRROR) {
|
||||
|
@ -3677,8 +3676,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
|
|||
+ glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0)
|
||||
+ mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
|
||||
+ mirrorBodyOrientation * hmdOffset);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
const float YAW_SPEED = TWO_PI / 5.0f;
|
||||
float deltaYaw = userInputMapper->getActionState(controller::Action::YAW) * YAW_SPEED * deltaTime;
|
||||
|
@ -3699,8 +3697,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
|
|||
_myCamera.setOrientation(cameraEntity->getWorldOrientation() * hmdRotation);
|
||||
glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
|
||||
_myCamera.setPosition(cameraEntity->getWorldPosition() + (hmdRotation * hmdOffset));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
_myCamera.setOrientation(cameraEntity->getWorldOrientation());
|
||||
_myCamera.setPosition(cameraEntity->getWorldPosition());
|
||||
}
|
||||
|
|
|
@ -958,7 +958,7 @@ void MyAvatar::simulate(float deltaTime, bool inView) {
|
|||
head->setScale(getModelScale());
|
||||
head->simulate(deltaTime);
|
||||
CameraMode mode = qApp->getCamera().getMode();
|
||||
if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {
|
||||
if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {
|
||||
if (!_pointAtActive || !_isPointTargetValid) {
|
||||
updateHeadLookAt(deltaTime);
|
||||
} else {
|
||||
|
@ -2718,7 +2718,8 @@ void MyAvatar::updateMotors() {
|
|||
if (_motionBehaviors & AVATAR_MOTION_ACTION_MOTOR_ENABLED) {
|
||||
if (_characterController.getState() == CharacterController::State::Hover ||
|
||||
_characterController.computeCollisionMask() == BULLET_COLLISION_MASK_COLLISIONLESS) {
|
||||
if (qApp->getCamera().getMode() == CAMERA_MODE_LOOK_AT || qApp->getCamera().getMode() == CAMERA_MODE_SELFIE) {
|
||||
CameraMode mode = qApp->getCamera().getMode();
|
||||
if (mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {
|
||||
motorRotation = getLookAtRotation();
|
||||
} else {
|
||||
motorRotation = getMyHead()->getHeadOrientation();
|
||||
|
@ -3442,8 +3443,10 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
// Smoothly rotate body with arrow keys
|
||||
float targetSpeed = getDriveKey(YAW) * _yawSpeed;
|
||||
CameraMode mode = qApp->getCamera().getMode();
|
||||
bool computeLookAt = (mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) && isReadyForPhysics() && !qApp->isHMDMode();
|
||||
if (computeLookAt) {
|
||||
bool computeLookAt = isReadyForPhysics() && !qApp->isHMDMode() &&
|
||||
(mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE);
|
||||
bool smoothCameraYaw = computeLookAt && mode != CAMERA_MODE_FIRST_PERSON;
|
||||
if (smoothCameraYaw) {
|
||||
// For "Look At" and "Selfie" camera modes we also smooth the yaw rotation from right-click mouse movement.
|
||||
float speedFromDeltaYaw = deltaTime > FLT_EPSILON ? getDriveKey(DELTA_YAW) / deltaTime : 0.0f;
|
||||
speedFromDeltaYaw *= _yawSpeed / YAW_SPEED_DEFAULT;
|
||||
|
@ -3472,7 +3475,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
}
|
||||
}
|
||||
float totalBodyYaw = _bodyYawDelta * deltaTime;
|
||||
if (!computeLookAt) {
|
||||
if (!smoothCameraYaw) {
|
||||
// Rotate directly proportional to delta yaw and delta pitch from right-click mouse movement.
|
||||
totalBodyYaw += getDriveKey(DELTA_YAW) * _yawSpeed / YAW_SPEED_DEFAULT;
|
||||
}
|
||||
|
@ -3563,12 +3566,16 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
blend = 1.0f;
|
||||
}
|
||||
glm::quat faceRotation = _lookAtYaw;
|
||||
if (isMovingFwdBwd && isMovingSideways) {
|
||||
// Reorient avatar to face camera diagonal
|
||||
blend = DIAGONAL_TURN_BLEND;
|
||||
float turnSign = getDriveKey(TRANSLATE_Z) < 0.0f ? -1.0f : 1.0f;
|
||||
turnSign = getDriveKey(TRANSLATE_X) > 0.0f ? -turnSign : turnSign;
|
||||
faceRotation = _lookAtYaw * glm::angleAxis(turnSign * 0.25f * PI, Vectors::UP);
|
||||
if (isMovingFwdBwd) {
|
||||
if (isMovingSideways) {
|
||||
// Reorient avatar to face camera diagonal
|
||||
blend = mode == CAMERA_MODE_FIRST_PERSON ? 1.0f : DIAGONAL_TURN_BLEND;
|
||||
float turnSign = getDriveKey(TRANSLATE_Z) < 0.0f ? -1.0f : 1.0f;
|
||||
turnSign = getDriveKey(TRANSLATE_X) > 0.0f ? -turnSign : turnSign;
|
||||
faceRotation = _lookAtYaw * glm::angleAxis(turnSign * 0.25f * PI, Vectors::UP);
|
||||
} else if (mode == CAMERA_MODE_FIRST_PERSON) {
|
||||
blend = 1.0f;
|
||||
}
|
||||
}
|
||||
setWorldOrientation(glm::slerp(getWorldOrientation(), faceRotation, blend));
|
||||
} else if (isRotatingWhileSeated) {
|
||||
|
@ -3630,20 +3637,32 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
glm::vec3 avatarVectorRight = getWorldOrientation() * Vectors::RIGHT;
|
||||
float leftRightDot = glm::dot(cameraYawVector, avatarVectorRight);
|
||||
|
||||
const float REORIENT_ANGLE = 65.0f;
|
||||
const float DEFAULT_REORIENT_ANGLE = 65.0f;
|
||||
const float FIRST_PERSON_REORIENT_ANGLE = 95.0f;
|
||||
const float TRIGGER_REORIENT_ANGLE = 45.0f;
|
||||
const float FIRST_PERSON_TRIGGER_REORIENT_ANGLE = 65.0f;
|
||||
glm::vec3 ajustedYawVector = cameraYawVector;
|
||||
if (frontBackDot < 0.0f) {
|
||||
ajustedYawVector = (leftRightDot < 0.0f ? -avatarVectorRight : avatarVectorRight);
|
||||
cameraVector = (ajustedYawVector * _lookAtPitch) * Vectors::FRONT;
|
||||
float limitAngle = 0.0f;
|
||||
float triggerAngle = -glm::sin(glm::radians(TRIGGER_REORIENT_ANGLE));
|
||||
if (mode == CAMERA_MODE_FIRST_PERSON) {
|
||||
limitAngle = glm::sin(glm::radians(90.0f - FIRST_PERSON_TRIGGER_REORIENT_ANGLE));
|
||||
triggerAngle = limitAngle;
|
||||
}
|
||||
float reorientAngle = mode == CAMERA_MODE_FIRST_PERSON ? FIRST_PERSON_REORIENT_ANGLE : DEFAULT_REORIENT_ANGLE;
|
||||
if (frontBackDot < limitAngle) {
|
||||
if (frontBackDot < 0.0f) {
|
||||
ajustedYawVector = (leftRightDot < 0.0f ? -avatarVectorRight : avatarVectorRight);
|
||||
cameraVector = (ajustedYawVector * _lookAtPitch) * Vectors::FRONT;
|
||||
}
|
||||
if (!isRotatingWhileSeated) {
|
||||
if (frontBackDot < -glm::sin(glm::radians(TRIGGER_REORIENT_ANGLE))) {
|
||||
if (frontBackDot < triggerAngle) {
|
||||
_shouldTurnToFaceCamera = true;
|
||||
_firstPersonSteadyHeadTimer = 0.0f;
|
||||
}
|
||||
} else {
|
||||
setWorldOrientation(previousOrientation);
|
||||
}
|
||||
} else if (frontBackDot > glm::sin(glm::radians(REORIENT_ANGLE))) {
|
||||
} else if (frontBackDot > glm::sin(glm::radians(reorientAngle))) {
|
||||
_shouldTurnToFaceCamera = false;
|
||||
}
|
||||
|
||||
|
@ -3664,6 +3683,22 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
_lookAtCameraTarget = targetPoint;
|
||||
}
|
||||
_headLookAtActive = true;
|
||||
const float FIRST_PERSON_RECENTER_SECONDS = 15.0f;
|
||||
if (mode == CAMERA_MODE_FIRST_PERSON) {
|
||||
if (getDriveKey(YAW) + getDriveKey(STEP_YAW) + getDriveKey(DELTA_YAW) == 0.0f) {
|
||||
if (_firstPersonSteadyHeadTimer < FIRST_PERSON_RECENTER_SECONDS) {
|
||||
if (_firstPersonSteadyHeadTimer > 0.0f) {
|
||||
_firstPersonSteadyHeadTimer += deltaTime;
|
||||
}
|
||||
} else {
|
||||
_shouldTurnToFaceCamera = true;
|
||||
_firstPersonSteadyHeadTimer = 0.0f;
|
||||
}
|
||||
} else {
|
||||
_firstPersonSteadyHeadTimer = deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
head->setBaseYaw(0.0f);
|
||||
head->setBasePitch(getHead()->getBasePitch() + getDriveKey(PITCH) * _pitchSpeed * deltaTime
|
||||
|
@ -3736,7 +3771,8 @@ glm::vec3 MyAvatar::scaleMotorSpeed(const glm::vec3 forward, const glm::vec3 rig
|
|||
} else {
|
||||
// Desktop mode.
|
||||
direction = (zSpeed * forward) + (xSpeed * right);
|
||||
if (qApp->getCamera().getMode() == CAMERA_MODE_LOOK_AT && zSpeed != 0.0f && xSpeed != 0.0f){
|
||||
CameraMode mode = qApp->getCamera().getMode();
|
||||
if ((mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_SELFIE) && zSpeed != 0.0f && xSpeed != 0.0f){
|
||||
direction = (zSpeed * forward);
|
||||
}
|
||||
|
||||
|
@ -4351,7 +4387,8 @@ bool MyAvatar::isFlying() {
|
|||
|
||||
bool MyAvatar::isInAir() {
|
||||
// If Avatar is Hover, Falling, or Taking off, they are in Air.
|
||||
return _characterController.getState() != CharacterController::State::Ground;
|
||||
return _characterController.getState() != CharacterController::State::Ground &&
|
||||
_characterController.getState() != CharacterController::State::Seated;
|
||||
}
|
||||
|
||||
bool MyAvatar::getFlyingEnabled() {
|
||||
|
@ -5399,7 +5436,7 @@ glm::quat MyAvatar::getOrientationForAudio() {
|
|||
case AudioListenerMode::FROM_HEAD: {
|
||||
// Using the camera's orientation instead, when the current mode is controlling the avatar's head.
|
||||
CameraMode mode = qApp->getCamera().getMode();
|
||||
bool headFollowsCamera = mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE;
|
||||
bool headFollowsCamera = mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE;
|
||||
result = headFollowsCamera ? qApp->getCamera().getOrientation() : getHead()->getFinalOrientationInWorldFrame();
|
||||
break;
|
||||
}
|
||||
|
@ -6768,6 +6805,12 @@ void MyAvatar::setHeadLookAt(const glm::vec3& lookAtTarget) {
|
|||
_lookAtScriptTarget = lookAtTarget;
|
||||
}
|
||||
|
||||
glm::vec3 MyAvatar::getLookAtPivotPoint() {
|
||||
glm::vec3 avatarUp = getWorldOrientation() * Vectors::UP;
|
||||
glm::vec3 yAxisEyePosition = getWorldPosition() + avatarUp * glm::dot(avatarUp, _skeletonModel->getDefaultEyeModelPosition());
|
||||
return yAxisEyePosition;
|
||||
}
|
||||
|
||||
bool MyAvatar::setPointAt(const glm::vec3& pointAtTarget) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
bool result = false;
|
||||
|
@ -6794,3 +6837,4 @@ void MyAvatar::resetPointAt() {
|
|||
POINT_BLEND_LINEAR_ALPHA_NAME, POINT_ALPHA_BLENDING);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -272,11 +272,12 @@ class MyAvatar : public Avatar {
|
|||
* the value.</p>
|
||||
* @property {number} analogPlusSprintSpeed - The sprint (run) speed of your avatar for the "AnalogPlus" control scheme.
|
||||
* @property {MyAvatar.SitStandModelType} userRecenterModel - Controls avatar leaning and recentering behavior.
|
||||
* @property {number} isInSittingState - <code>true</code> if your avatar is sitting (avatar leaning is disabled,
|
||||
* recenntering is enabled), <code>false</code> if it is standing (avatar leaning is enabled, and avatar recenters if it
|
||||
* leans too far). If <code>userRecenterModel == 2</code> (i.e., auto) the property value automatically updates as the
|
||||
* user sits or stands, unless <code>isSitStandStateLocked == true</code>. Setting the property value overrides the
|
||||
* current siting / standing state, which is updated when the user next sits or stands unless
|
||||
* @property {number} isInSittingState - <code>true</code> if the user wearing the HMD is determined to be sitting
|
||||
* (avatar leaning is disabled, recenntering is enabled), <code>false</code> if the user wearing the HMD is
|
||||
* determined to be standing (avatar leaning is enabled, and avatar recenters if it leans too far).
|
||||
* If <code>userRecenterModel == 2</code> (i.e., auto) the property value automatically updates as the user sits
|
||||
* or stands, unless <code>isSitStandStateLocked == true</code>. Setting the property value overrides the current
|
||||
* siting / standing state, which is updated when the user next sits or stands unless
|
||||
* <code>isSitStandStateLocked == true</code>.
|
||||
* @property {boolean} isSitStandStateLocked - <code>true</code> to lock the avatar sitting/standing state, i.e., use this
|
||||
* to disable automatically changing state.
|
||||
|
@ -1890,6 +1891,14 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE void endSit(const glm::vec3& position, const glm::quat& rotation);
|
||||
|
||||
/**jsdoc
|
||||
* Gets whether the avatar is in a seated pose. The seated pose is set by calling the
|
||||
* MyAvatar::beginSit method.
|
||||
* @function MyAvatar.isSeated
|
||||
* @returns {boolean} <code>true</code> if the avatar is in a seated pose.
|
||||
*/
|
||||
Q_INVOKABLE bool isSeated() { return _characterController.getSeated(); }
|
||||
|
||||
int getOverrideJointCount() const;
|
||||
bool getFlowActive() const;
|
||||
bool getNetworkGraphActive() const;
|
||||
|
@ -1906,6 +1915,7 @@ public:
|
|||
void debugDrawPose(controller::Action action, const char* channelName, float size);
|
||||
|
||||
bool getIsJointOverridden(int jointIndex) const;
|
||||
glm::vec3 getLookAtPivotPoint();
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -2663,6 +2673,7 @@ private:
|
|||
bool _shouldTurnToFaceCamera { false };
|
||||
bool _scriptControlsHeadLookAt { false };
|
||||
float _scriptHeadControlTimer { 0.0f };
|
||||
float _firstPersonSteadyHeadTimer { 0.0f };
|
||||
bool _pointAtActive { false };
|
||||
bool _isPointTargetValid { true };
|
||||
|
||||
|
|
|
@ -6,5 +6,7 @@
|
|||
<array>
|
||||
<string>high-fidelity.hifi</string>
|
||||
</array>
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -92,22 +92,23 @@ void Head::simulate(float deltaTime) {
|
|||
} else if (_timeWithoutTalking - deltaTime < BLINK_AFTER_TALKING && _timeWithoutTalking >= BLINK_AFTER_TALKING) {
|
||||
forceBlink = true;
|
||||
}
|
||||
|
||||
if (_leftEyeBlinkVelocity == 0.0f && _rightEyeBlinkVelocity == 0.0f) {
|
||||
// no blinking when brows are raised; blink less with increasing loudness
|
||||
const float BASE_BLINK_RATE = 15.0f / 60.0f;
|
||||
const float ROOT_LOUDNESS_TO_BLINK_INTERVAL = 0.25f;
|
||||
if (forceBlink || (_browAudioLift < EPSILON && shouldDo(glm::max(1.0f, sqrt(fabs(_averageLoudness - _longTermAverageLoudness)) *
|
||||
ROOT_LOUDNESS_TO_BLINK_INTERVAL) / BASE_BLINK_RATE, deltaTime))) {
|
||||
_leftEyeBlinkVelocity = BLINK_SPEED + randFloat() * BLINK_SPEED_VARIABILITY;
|
||||
_rightEyeBlinkVelocity = BLINK_SPEED + randFloat() * BLINK_SPEED_VARIABILITY;
|
||||
float randSpeedVariability = randFloat();
|
||||
float eyeBlinkVelocity = BLINK_SPEED + randSpeedVariability * BLINK_SPEED_VARIABILITY;
|
||||
_leftEyeBlinkVelocity = eyeBlinkVelocity;
|
||||
_rightEyeBlinkVelocity = eyeBlinkVelocity;
|
||||
if (randFloat() < 0.5f) {
|
||||
_leftEyeBlink = BLINK_START_VARIABILITY;
|
||||
} else {
|
||||
_rightEyeBlink = BLINK_START_VARIABILITY;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
_leftEyeBlink = glm::clamp(_leftEyeBlink + _leftEyeBlinkVelocity * deltaTime, FULLY_OPEN, FULLY_CLOSED);
|
||||
_rightEyeBlink = glm::clamp(_rightEyeBlink + _rightEyeBlinkVelocity * deltaTime, FULLY_OPEN, FULLY_CLOSED);
|
||||
|
||||
|
|
|
@ -96,6 +96,21 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
|
|||
connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, handlePointerEvent);
|
||||
connect(entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity, this, handlePointerEvent);
|
||||
connect(entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity, this, handlePointerEvent);
|
||||
// Handle mouse-clicking or laser-clicking on entities with the `href` property set
|
||||
connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, [&](const QUuid& entityID, const PointerEvent& event) {
|
||||
if (!EntityTree::areEntityClicksCaptured() && (event.getButtons() & PointerEvent::PrimaryButton)) {
|
||||
auto entity = getEntity(entityID);
|
||||
if (!entity) {
|
||||
return;
|
||||
}
|
||||
auto properties = entity->getProperties();
|
||||
QString urlString = properties.getHref();
|
||||
QUrl url = QUrl(urlString, QUrl::StrictMode);
|
||||
if (url.isValid() && !url.isEmpty()) {
|
||||
DependencyManager::get<AddressManager>()->handleLookupString(urlString);
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity, this, [&](const QUuid& entityID, const PointerEvent& event) {
|
||||
std::shared_ptr<render::entities::WebEntityRenderer> thisEntity;
|
||||
auto entity = getEntity(entityID);
|
||||
|
@ -800,15 +815,6 @@ QUuid EntityTreeRenderer::mousePressEvent(QMouseEvent* event) {
|
|||
RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID);
|
||||
EntityItemPointer entity;
|
||||
if (rayPickResult.intersects && (entity = getTree()->findEntityByID(rayPickResult.entityID))) {
|
||||
if (!EntityTree::areEntityClicksCaptured() && event->button() == Qt::MouseButton::LeftButton) {
|
||||
auto properties = entity->getProperties();
|
||||
QString urlString = properties.getHref();
|
||||
QUrl url = QUrl(urlString, QUrl::StrictMode);
|
||||
if (url.isValid() && !url.isEmpty()) {
|
||||
DependencyManager::get<AddressManager>()->handleLookupString(urlString);
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Press, PointerManager::MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
|
|
|
@ -706,15 +706,11 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
*
|
||||
* @property {Vec3} gravity=0,0,0 - The acceleration due to gravity in m/s<sup>2</sup> that the entity should move with, in
|
||||
* world coordinates. Use a value of <code>{ x: 0, y: -9.8, z: 0 }</code> to simulate Earth's gravity. Gravity is applied
|
||||
* to an entity's motion only if its <code>dynamic</code> property is <code>true</code>. The <code>gravity</code> value is
|
||||
* applied in addition to the <code>acceleration</code> value.
|
||||
* to an entity's motion only if its <code>dynamic</code> property is <code>true</code>.
|
||||
* <p>If changing an entity's <code>gravity</code> from {@link Vec3(0)|Vec3.ZERO}, you need to give it a small
|
||||
* <code>velocity</code> in order to kick off physics simulation.</p>
|
||||
* @property {Vec3} acceleration=0,0,0 - A general acceleration in m/s<sup>2</sup> that the entity should move with, in world
|
||||
* coordinates. The acceleration is applied to an entity's motion only if its <code>dynamic</code> property is
|
||||
* <code>true</code>. The <code>acceleration</code> value is applied in addition to the <code>gravity</code> value.
|
||||
* <p>If changing an entity's <code>acceleration</code> from {@link Vec3(0)|Vec3.ZERO}, you need to give it a small
|
||||
* <code>velocity</code> in order to kick off physics simulation.<p>
|
||||
* @property {Vec3} acceleration - The current, measured acceleration of the entity, in m/s<sup>2</sup>.
|
||||
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
||||
* @property {number} restitution=0.5 - The "bounciness" of an entity when it collides, range <code>0.0</code> –
|
||||
* <code>0.99</code>. The higher the value, the more bouncy.
|
||||
* @property {number} friction=0.5 - How much an entity slows down when it's moving against another, range <code>0.0</code>
|
||||
|
|
|
@ -728,7 +728,8 @@ public slots:
|
|||
* Finds all domain and avatar entities whose axis-aligned boxes intersect a search frustum.
|
||||
* @function Entities.findEntitiesInFrustum
|
||||
* @param {ViewFrustum} frustum - The frustum to search in. The <code>position</code>, <code>orientation</code>,
|
||||
* <code>projection</code>, and <code>centerRadius</code> properties must be specified.
|
||||
* <code>projection</code>, and <code>centerRadius</code> properties must be specified. The <code>fieldOfView</code>
|
||||
* and <code>aspectRatio</code> properties are not used; these values are specified by the <code>projection</code>.
|
||||
* @returns {Uuid[]} An array of entity IDs whose axis-aligned boxes intersect the search frustum. The array is empty if no
|
||||
* entities could be found.
|
||||
* @example <caption>Report the number of entities in view.</caption>
|
||||
|
|
|
@ -1035,7 +1035,7 @@ void AccountManager::publicKeyUploadSucceeded(QNetworkReply* reply) {
|
|||
|
||||
void AccountManager::publicKeyUploadFailed(QNetworkReply* reply) {
|
||||
// the public key upload has failed
|
||||
qWarning() << "Public key upload failed from AccountManager" << reply->errorString();
|
||||
qCritical() << "PAGE: Public key upload failed from AccountManager to" << reply->url() << reply->errorString();
|
||||
|
||||
// we aren't waiting for a response any longer
|
||||
_isWaitingForKeypairResponse = false;
|
||||
|
|
|
@ -234,14 +234,38 @@ const JSONCallbackParameters& AddressManager::apiCallbackParameters() {
|
|||
return callbackParams;
|
||||
}
|
||||
|
||||
bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
||||
bool AddressManager::handleUrl(const QUrl& lookupUrlIn, LookupTrigger trigger) {
|
||||
static QString URL_TYPE_USER = "user";
|
||||
static QString URL_TYPE_DOMAIN_ID = "domain_id";
|
||||
static QString URL_TYPE_PLACE = "place";
|
||||
static QString URL_TYPE_NETWORK_ADDRESS = "network_address";
|
||||
if (lookupUrl.scheme() == URL_SCHEME_HIFI) {
|
||||
|
||||
qCDebug(networking) << "Trying to go to URL" << lookupUrl.toString();
|
||||
QUrl lookupUrl = lookupUrlIn;
|
||||
|
||||
qCDebug(networking) << "Trying to go to URL" << lookupUrl.toString();
|
||||
|
||||
if (lookupUrl.scheme().isEmpty() && !lookupUrl.path().startsWith("/")) {
|
||||
// 'urls' without schemes are taken as domain names, as opposed to
|
||||
// simply a path portion of a url, so we need to set the scheme
|
||||
lookupUrl.setScheme(URL_SCHEME_HIFI);
|
||||
}
|
||||
|
||||
static const QRegExp PORT_REGEX = QRegExp("\\d{1,5}(\\/.*)?");
|
||||
if(!lookupUrl.scheme().isEmpty() && lookupUrl.host().isEmpty() && PORT_REGEX.exactMatch(lookupUrl.path())) {
|
||||
// this is in the form somewhere:<port>, convert it to hifi://somewhere:<port>
|
||||
lookupUrl = QUrl(URL_SCHEME_HIFI + "://" + lookupUrl.toString());
|
||||
}
|
||||
// it should be noted that url's in the form
|
||||
// somewhere:<port> are not valid, as that
|
||||
// would indicate that the scheme is 'somewhere'
|
||||
// use hifi://somewhere:<port> instead
|
||||
|
||||
if (lookupUrl.scheme() == URL_SCHEME_HIFI) {
|
||||
if (lookupUrl.host().isEmpty()) {
|
||||
// this was in the form hifi:/somewhere or hifi:somewhere. Fix it by making it hifi://somewhere
|
||||
static const QRegExp HIFI_SCHEME_REGEX = QRegExp(URL_SCHEME_HIFI + ":\\/?", Qt::CaseInsensitive);
|
||||
lookupUrl = QUrl(lookupUrl.toString().replace(HIFI_SCHEME_REGEX, URL_SCHEME_HIFI + "://"));
|
||||
}
|
||||
|
||||
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::LookupAddress);
|
||||
|
||||
|
@ -379,25 +403,11 @@ bool isPossiblePlaceName(QString possiblePlaceName) {
|
|||
}
|
||||
|
||||
void AddressManager::handleLookupString(const QString& lookupString, bool fromSuggestions) {
|
||||
if (!lookupString.isEmpty()) {
|
||||
|
||||
QString sanitizedString = lookupString.trimmed();
|
||||
if (!sanitizedString.isEmpty()) {
|
||||
// make this a valid hifi URL and handle it off to handleUrl
|
||||
QString sanitizedString = lookupString.trimmed();
|
||||
QUrl lookupURL;
|
||||
|
||||
if (!lookupString.startsWith('/')) {
|
||||
// sometimes we need to handle lookupStrings like hifi:/somewhere
|
||||
const QRegExp HIFI_SCHEME_REGEX = QRegExp(URL_SCHEME_HIFI + ":\\/{1,2}", Qt::CaseInsensitive);
|
||||
sanitizedString = sanitizedString.remove(HIFI_SCHEME_REGEX);
|
||||
|
||||
lookupURL = QUrl(sanitizedString);
|
||||
if (lookupURL.scheme().isEmpty() || lookupURL.scheme().toLower() == LOCALHOST) {
|
||||
lookupURL = QUrl("hifi://" + sanitizedString);
|
||||
}
|
||||
} else {
|
||||
lookupURL = QUrl(sanitizedString);
|
||||
}
|
||||
|
||||
handleUrl(lookupURL, fromSuggestions ? Suggestions : UserInput);
|
||||
handleUrl(sanitizedString, fromSuggestions ? Suggestions : UserInput);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ LimitedNodeList::LimitedNodeList(int socketListenPort, int dtlsListenPort) :
|
|||
_nodeSocket.bind(QHostAddress::AnyIPv4, port);
|
||||
quint16 assignedPort = _nodeSocket.localPort();
|
||||
if (socketListenPort != INVALID_PORT && socketListenPort != 0 && socketListenPort != assignedPort) {
|
||||
qCCritical(networking) << "NodeList is unable to assign requested port of" << socketListenPort;
|
||||
qCCritical(networking) << "PAGE: NodeList is unable to assign requested port of" << socketListenPort;
|
||||
}
|
||||
qCDebug(networking) << "NodeList socket is listening on" << assignedPort;
|
||||
|
||||
|
@ -1155,6 +1155,7 @@ void LimitedNodeList::startSTUNPublicSocketUpdate() {
|
|||
void LimitedNodeList::possiblyTimeoutSTUNAddressLookup() {
|
||||
if (_stunSockAddr.getAddress().isNull()) {
|
||||
// our stun address is still NULL, but we've been waiting for long enough - time to force a fail
|
||||
qCCritical(networking) << "PAGE: Failed to lookup address of STUN server" << STUN_SERVER_HOSTNAME;
|
||||
stopInitialSTUNUpdate(false);
|
||||
}
|
||||
}
|
||||
|
@ -1170,7 +1171,7 @@ void LimitedNodeList::stopInitialSTUNUpdate(bool success) {
|
|||
if (!success) {
|
||||
// if we're here this was the last failed STUN request
|
||||
// use our DS as our stun server
|
||||
qCDebug(networking, "Failed to lookup public address via STUN server at %s:%hu.",
|
||||
qCWarning(networking, "PAGE: Failed to lookup public address via STUN server at %s:%hu (likely a critical error for auto-networking).",
|
||||
STUN_SERVER_HOSTNAME, STUN_SERVER_PORT);
|
||||
qCDebug(networking) << "LimitedNodeList public socket will be set with local port and null QHostAddress.";
|
||||
|
||||
|
@ -1212,7 +1213,8 @@ void LimitedNodeList::updateLocalSocket() {
|
|||
QTcpSocket* localIPTestSocket = new QTcpSocket;
|
||||
|
||||
connect(localIPTestSocket, &QTcpSocket::connected, this, &LimitedNodeList::connectedForLocalSocketTest);
|
||||
connect(localIPTestSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(errorTestingLocalSocket()));
|
||||
connect(localIPTestSocket, static_cast<void(QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error),
|
||||
this, &LimitedNodeList::errorTestingLocalSocket);
|
||||
|
||||
// attempt to connect to our reliable host
|
||||
localIPTestSocket->connectToHost(RELIABLE_LOCAL_IP_CHECK_HOST, RELIABLE_LOCAL_IP_CHECK_PORT);
|
||||
|
@ -1242,6 +1244,8 @@ void LimitedNodeList::errorTestingLocalSocket() {
|
|||
// then use our possibly updated guessed local address as fallback
|
||||
if (!_hasTCPCheckedLocalSocket) {
|
||||
setLocalSocket(HifiSockAddr { getGuessedLocalAddress(), _nodeSocket.localPort() });
|
||||
qCCritical(networking) << "PAGE: Can't connect to Google DNS service via TCP, falling back to guessed local address"
|
||||
<< getLocalSockAddr();
|
||||
}
|
||||
|
||||
localIPTestSocket->deleteLater();
|
||||
|
@ -1325,7 +1329,7 @@ void LimitedNodeList::putLocalPortIntoSharedMemory(const QString key, QObject* p
|
|||
|
||||
qCDebug(networking) << "Wrote local listening port" << localPort << "to shared memory at key" << key;
|
||||
} else {
|
||||
qWarning() << "Failed to create and attach to shared memory to share local port with assignment-client children.";
|
||||
qWarning() << "ALERT: Failed to create and attach to shared memory to share local port with assignment-client children.";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include <shared/QtHelpers.h>
|
||||
#include <Gzip.h>
|
||||
|
||||
#include <future>
|
||||
|
||||
using Promise = MiniPromise::Promise;
|
||||
|
||||
AssetScriptingInterface::AssetScriptingInterface(QObject* parent) : BaseAssetScriptingInterface(parent) {
|
||||
|
@ -38,6 +40,25 @@ AssetScriptingInterface::AssetScriptingInterface(QObject* parent) : BaseAssetScr
|
|||
|
||||
#define JS_VERIFY(cond, error) { if (!this->jsVerify(cond, error)) { return; } }
|
||||
|
||||
bool AssetScriptingInterface::initializeCache() {
|
||||
if (!Parent::initializeCache()) {
|
||||
if (assetClient()) {
|
||||
std::promise<bool> cacheStatusResult;
|
||||
Promise assetClientPromise(makePromise(__func__));
|
||||
assetClientPromise->moveToThread(qApp->thread()); // To ensure the finally() is processed.
|
||||
|
||||
assetClient()->cacheInfoRequestAsync(assetClientPromise);
|
||||
assetClientPromise->finally([&](QString, QVariantMap result)
|
||||
{ cacheStatusResult.set_value(!result.isEmpty()); });
|
||||
return cacheStatusResult.get_future().get();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetScriptingInterface::uploadData(QString data, QScriptValue callback) {
|
||||
auto handler = jsBindCallback(thisObject(), callback);
|
||||
QByteArray dataByteArray = data.toUtf8();
|
||||
|
|
|
@ -356,7 +356,7 @@ public:
|
|||
* @function Assets.initializeCache
|
||||
* @returns {boolean} <code>true</code> if the cache is initialized, <code>false</code> if it isn't.
|
||||
*/
|
||||
Q_INVOKABLE bool initializeCache() { return Parent::initializeCache(); }
|
||||
Q_INVOKABLE bool initializeCache();
|
||||
|
||||
/**jsdoc
|
||||
* Checks whether the script can write to the cache.
|
||||
|
|
|
@ -70,15 +70,16 @@ glm::mat4 Mat4::inverse(const glm::mat4& m) const {
|
|||
}
|
||||
|
||||
glm::vec3 Mat4::getForward(const glm::mat4& m) const {
|
||||
return glm::vec3(-m[0][2], -m[1][2], -m[2][2]);
|
||||
// -z is forward
|
||||
return -glm::normalize(glm::vec3(m[2]));
|
||||
}
|
||||
|
||||
glm::vec3 Mat4::getRight(const glm::mat4& m) const {
|
||||
return glm::vec3(m[0][0], m[1][0], m[2][0]);
|
||||
return glm::normalize(glm::vec3(m[0]));
|
||||
}
|
||||
|
||||
glm::vec3 Mat4::getUp(const glm::mat4& m) const {
|
||||
return glm::vec3(m[0][1], m[1][1], m[2][1]);
|
||||
return glm::normalize(glm::vec3(m[1]));
|
||||
}
|
||||
|
||||
void Mat4::print(const QString& label, const glm::mat4& m, bool transpose) const {
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
#include "RegisteredMetaTypes.h"
|
||||
|
||||
/**jsdoc
|
||||
* The <code>Mat4</code> API provides facilities for generating and using 4 x 4 matrices. These matrices are typically used to
|
||||
* represent transforms (scale, rotate, and translate) that convert one coordinate system into another, or perspective
|
||||
* transforms that convert 3D points into screen coordinates.
|
||||
*
|
||||
* @namespace Mat4
|
||||
* @variation 0
|
||||
*
|
||||
|
@ -39,130 +43,279 @@ class Mat4 : public QObject, protected QScriptable {
|
|||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
* Multiplies two matrices.
|
||||
* @function Mat4(0).multiply
|
||||
* @param {Mat4} m1
|
||||
* @param {Mat4} m2
|
||||
* @returns {Mat4}
|
||||
* @param {Mat4} m1 - The first matrix.
|
||||
* @param {Mat4} m2 - The second matrix.
|
||||
* @returns {Mat4} <code>m1</code> multiplied with <code>m2</code>.
|
||||
*/
|
||||
glm::mat4 multiply(const glm::mat4& m1, const glm::mat4& m2) const;
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Creates a matrix that represents a rotation and translation.
|
||||
* @function Mat4(0).createFromRotAndTrans
|
||||
* @param {Quat} rot
|
||||
* @param {Vec3} trans
|
||||
* @returns {Mat4}
|
||||
* @param {Quat} rot - The rotation.
|
||||
* @param {Vec3} trans - The translation.
|
||||
* @returns {Mat4} The matrix that represents the rotation and translation.
|
||||
* @example <caption>Create a matrix with rotation and translation.</caption>
|
||||
* var rot = Quat.fromPitchYawRollDegrees(30, 45, 60);
|
||||
* var trans = { x: 10, y: 11, z: 12 };
|
||||
* var matrix = Mat4.createFromRotAndTrans(rot, trans);
|
||||
* Mat4.print("Matrix:", matrix);
|
||||
* // Matrix: dmat4x4((0.353553, 0.612372, -0.707107, 0.000000),
|
||||
* // (-0.573223, 0.739199, 0.353553, 0.000000),
|
||||
* // (0.739199, 0.280330, 0.612372, 0.000000),
|
||||
* // (10.000000, 11.000000, 12.000000, 1.000000))
|
||||
*/
|
||||
glm::mat4 createFromRotAndTrans(const glm::quat& rot, const glm::vec3& trans) const;
|
||||
|
||||
/**jsdoc
|
||||
* Creates a matrix that represents a scale, rotation, and translation.
|
||||
* @function Mat4(0).createFromScaleRotAndTrans
|
||||
* @param {Vec3} scale
|
||||
* @param {Quat} rot
|
||||
* @param {Vec3} trans
|
||||
* @returns {Mat4}
|
||||
* @param {Vec3} scale - The scale.
|
||||
* @param {Quat} rot - The rotation.
|
||||
* @param {Vec3} trans - The translation.
|
||||
* @returns {Mat4} The matrix that represents the scale, rotation, and translation.
|
||||
* @example <caption>Create a matrix with scale, rotation, and translation.</caption>
|
||||
* var scale = Vec3.multiply(2, Vec3.ONE);
|
||||
* var rot = Quat.fromPitchYawRollDegrees(30, 45, 60);
|
||||
* var trans = { x: 10, y: 11, z: 12 };
|
||||
* var matrix = Mat4.createFromScaleRotAndTrans(scale, rot, trans);
|
||||
* Mat4.print("Matrix:", matrix);
|
||||
* // Matrix: dmat4x4((0.707107, 1.224745, -1.414214, 0.000000),
|
||||
* // (-1.146447, 1.478398, 0.707107, 0.000000),
|
||||
* // (1.478398, 0.560660, 1.224745, 0.000000),
|
||||
* // (10.000000, 11.000000, 12.000000, 1.000000))
|
||||
*/
|
||||
glm::mat4 createFromScaleRotAndTrans(const glm::vec3& scale, const glm::quat& rot, const glm::vec3& trans) const;
|
||||
|
||||
/**jsdoc
|
||||
* Creates a matrix from columns of values.
|
||||
* @function Mat4(0).createFromColumns
|
||||
* @param {Vec4} col0
|
||||
* @param {Vec4} col1
|
||||
* @param {Vec4} col2
|
||||
* @param {Vec4} col
|
||||
* @returns {Mat4}
|
||||
* @param {Vec4} col0 - Column 0 values.
|
||||
* @param {Vec4} col1 - Column 1 values.
|
||||
* @param {Vec4} col2 - Column 2 values.
|
||||
* @param {Vec4} col3 - Column 3 valuse.
|
||||
* @returns {Mat4} The matrix with the specified columns values.
|
||||
* @example <caption>Create a matrix from columns.</caption>
|
||||
* var col0 = { x: 0.707107, y: 1.224745, z: -1.414214, w: 0.0 };
|
||||
* var col1 = { x: -1.146447, y: 1.478398, z: 0.707107, w: 0.0 };
|
||||
* var col2 = { x: 1.478398, y: 0.560660, z: 1.224745, w: 0.0 };
|
||||
* var col3 = { x: 10.0, y: 11.0, z: 12.0, w: 1.0 };
|
||||
* var matrix = Mat4.createFromColumns(col0, col1, col2, col3);
|
||||
* Mat4.print("Matrix:", matrix);
|
||||
* //Matrix: dmat4x4((0.707107, 1.224745, -1.414214, 0.000000),
|
||||
* // (-1.146447, 1.478398, 0.707107, 0.000000),
|
||||
* // (1.478398, 0.560660, 1.224745, 0.000000),
|
||||
* // (10.000000, 11.000000, 12.000000, 1.000000))
|
||||
*/
|
||||
glm::mat4 createFromColumns(const glm::vec4& col0, const glm::vec4& col1, const glm::vec4& col2, const glm::vec4& col3) const;
|
||||
|
||||
/**jsdoc
|
||||
* Creates a matrix from an array of values.
|
||||
* @function Mat4(0).createFromArray
|
||||
* @param {number[]} numbers
|
||||
* @returns {Mat4}
|
||||
* @param {number[]} arr - The array of values, starting with column 0.
|
||||
* @returns {Mat4} The matrix with the specified values.
|
||||
* @example <caption>Create a matrix from an array.</caption>
|
||||
* var arr = [
|
||||
* 0.707107, 1.224745, -1.414214, 0.0,
|
||||
* -1.146447, 1.478398, 0.707107, 0.0,
|
||||
* 1.478398, 0.560660, 1.224745, 0.0,
|
||||
* 10.0, 11.0, 12.0, 1.00
|
||||
* ];
|
||||
* var matrix = Mat4.createFromArray(arr);
|
||||
* Mat4.print("Matrix:", matrix);
|
||||
* //Matrix: dmat4x4((0.707107, 1.224745, -1.414214, 0.000000),
|
||||
* // (-1.146447, 1.478398, 0.707107, 0.000000),
|
||||
* // (1.478398, 0.560660, 1.224745, 0.000000),
|
||||
* // (10.000000, 11.000000, 12.000000, 1.000000))
|
||||
*/
|
||||
glm::mat4 createFromArray(const QVector<float>& floats) const;
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Extracts the translation from a matrix.
|
||||
* @function Mat4(0).extractTranslation
|
||||
* @param {Mat4} m
|
||||
* @returns {Vec3}
|
||||
* @param {Mat4} m - The matrix.
|
||||
* @returns {Vec3} The translation contained in the matrix.
|
||||
* @example <caption>Extract the translation from a matrix.</caption>
|
||||
* var scale = Vec3.multiply(2, Vec3.ONE);
|
||||
* var rot = Quat.fromPitchYawRollDegrees(30, 45, 60);
|
||||
* var trans = { x: 10, y: 11, z: 12 };
|
||||
* var matrix = Mat4.createFromScaleRotAndTrans(scale, rot, trans);
|
||||
*
|
||||
* trans = Mat4.extractTranslation(matrix);
|
||||
* print("Translation: " + JSON.stringify(trans));
|
||||
* // Translation: {"x":10,"y":11,"z":12}
|
||||
*/
|
||||
glm::vec3 extractTranslation(const glm::mat4& m) const;
|
||||
|
||||
/**jsdoc
|
||||
* Extracts the rotation from a matrix.
|
||||
* @function Mat4(0).extractRotation
|
||||
* @param {Mat4} m
|
||||
* @returns {Vec3}
|
||||
* @param {Mat4} m - The matrix.
|
||||
* @returns {Quat} The rotation contained in the matrix.
|
||||
* @example <caption>Extract the rotation from a matrix.</caption>
|
||||
* var scale = Vec3.multiply(2, Vec3.ONE);
|
||||
* var rot = Quat.fromPitchYawRollDegrees(30, 45, 60);
|
||||
* var trans = { x: 10, y: 11, z: 12 };
|
||||
* var matrix = Mat4.createFromScaleRotAndTrans(scale, rot, trans);
|
||||
*
|
||||
* rot = Mat4.extractRotation(matrix);
|
||||
* print("Rotation: " + JSON.stringify(Quat.safeEulerAngles(rot)));
|
||||
* // Rotation: {"x":29.999998092651367,"y":45.00000762939453,"z":60.000003814697266}
|
||||
*/
|
||||
glm::quat extractRotation(const glm::mat4& m) const;
|
||||
|
||||
/**jsdoc
|
||||
* Extracts the scale from a matrix.
|
||||
* @function Mat4(0).extractScale
|
||||
* @param {Mat4} m
|
||||
* @returns {Vec3}
|
||||
* @param {Mat4} m - The matrix.
|
||||
* @returns {Vec3} The scale contained in the matrix.
|
||||
* @example <caption>Extract the scale from a matrix.</caption>
|
||||
* var scale = Vec3.multiply(2, Vec3.ONE);
|
||||
* var rot = Quat.fromPitchYawRollDegrees(30, 45, 60);
|
||||
* var trans = { x: 10, y: 11, z: 12 };
|
||||
* var matrix = Mat4.createFromScaleRotAndTrans(scale, rot, trans);
|
||||
*
|
||||
* scale = Mat4.extractScale(matrix);
|
||||
* print("Scale: " + JSON.stringify(scale));
|
||||
* // Scale: {"x":1.9999998807907104,"y":1.9999998807907104,"z":1.9999998807907104}
|
||||
*/
|
||||
glm::vec3 extractScale(const glm::mat4& m) const;
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Transforms a point into a new coordinate system: the point value is scaled, rotated, and translated.
|
||||
* @function Mat4(0).transformPoint
|
||||
* @param {Mat4} m
|
||||
* @param {Vec3} point
|
||||
* @returns {Vec3}
|
||||
* @param {Mat4} m - The transform to the new coordinate system.
|
||||
* @param {Vec3} point - The point to transform.
|
||||
* @returns {Vec3} The point in the new coordinate system.
|
||||
* @example <caption>Transform a point.</caption>
|
||||
* var scale = Vec3.multiply(2, Vec3.ONE);
|
||||
* var rot = Quat.fromPitchYawRollDegrees(0, 45, 0);
|
||||
* var trans = { x: 0, y: 10, z: 0 };
|
||||
* var matrix = Mat4.createFromScaleRotAndTrans(scale, rot, trans);
|
||||
*
|
||||
* var point = { x: 1, y: 1, z: 1 };
|
||||
* var transformedPoint = Mat4.transformPoint(matrix, point);
|
||||
* print("Transformed point: " + JSON.stringify(transformedPoint));
|
||||
* // Transformed point: { "x": 2.8284270763397217, "y": 12, "z": -2.384185791015625e-7 }
|
||||
*/
|
||||
glm::vec3 transformPoint(const glm::mat4& m, const glm::vec3& point) const;
|
||||
|
||||
/**jsdoc
|
||||
* Transforms a vector into a new coordinate system: the vector is scaled and rotated.
|
||||
* @function Mat4(0).transformVector
|
||||
* @param {Mat4} m
|
||||
* @param {Vec3} vector
|
||||
* @returns {Vec3}
|
||||
* @param {Mat4} m - The transform to the new coordinate system.
|
||||
* @param {Vec3} vector - The vector to transform.
|
||||
* @returns {Vec3} The vector in the new coordinate system.
|
||||
* @example <caption>Transform a vector.</caption>
|
||||
* var scale = Vec3.multiply(2, Vec3.ONE);
|
||||
* var rot = Quat.fromPitchYawRollDegrees(0, 45, 0);
|
||||
* var trans = { x: 0, y: 10, z: 0 };
|
||||
* var matrix = Mat4.createFromScaleRotAndTrans(scale, rot, trans);
|
||||
*
|
||||
* var vector = { x: 1, y: 1, z: 1 };
|
||||
* var transformedVector = Mat4.transformVector(matrix, vector);
|
||||
* print("Transformed vector: " + JSON.stringify(transformedVector));
|
||||
* // Transformed vector: { "x": 2.8284270763397217, "y": 2, "z": -2.384185791015625e-7 }
|
||||
*/
|
||||
glm::vec3 transformVector(const glm::mat4& m, const glm::vec3& vector) const;
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Calculates the inverse of a matrix.
|
||||
* @function Mat4(0).inverse
|
||||
* @param {Mat4} m
|
||||
* @returns {Mat4}
|
||||
* @param {Mat4} m - The matrix.
|
||||
* @returns {Mat4} The inverse of the matrix.
|
||||
* @example <caption>A matrix multiplied with its inverse is the unit matrix.</caption>
|
||||
* var scale = Vec3.multiply(2, Vec3.ONE);
|
||||
* var rot = Quat.fromPitchYawRollDegrees(30, 45, 60);
|
||||
* var trans = { x: 10, y: 11, z: 12 };
|
||||
* var matrix = Mat4.createFromScaleRotAndTrans(scale, rot, trans);
|
||||
* var inverse = Mat4.inverse(matrix);
|
||||
* var multiplied = Mat4.multiply(matrix, inverse);
|
||||
* Mat4.print("Multiplied:", multiplied);
|
||||
* //Multiplied: dmat4x4((1.000000, 0.000000, 0.000000, 0.000000),
|
||||
* // (0.000000, 1.000000, -0.000000, 0.000000),
|
||||
* // (0.000000, 0.000000, 1.000000, 0.000000),
|
||||
* // (0.000000, 0.000000, 0.000001, 1.000000))
|
||||
*/
|
||||
glm::mat4 inverse(const glm::mat4& m) const;
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Gets the "forward" direction that the camera would face if its orientation was set to the rotation contained in a
|
||||
* matrix. The High Fidelity camera has axes x = right, y = up, -z = forward.
|
||||
* <p>Synonym for {@link Mat4(0).getForward|getForward}.</p>
|
||||
* @function Mat4(0).getFront
|
||||
* @param {Mat4} m
|
||||
* @returns {Vec3}
|
||||
* @param {Mat4} m - The matrix.
|
||||
* @returns {Vec3} The negative z-axis rotated by orientation.
|
||||
*/
|
||||
// redundant, calls getForward which better describes the returned vector as a direction
|
||||
glm::vec3 getFront(const glm::mat4& m) const { return getForward(m); }
|
||||
|
||||
/**jsdoc
|
||||
* Gets the "forward" direction that the camera would face if its orientation was set to the rotation contained in a
|
||||
* matrix. The High Fidelity camera has axes x = right, y = up, -z = forward.
|
||||
* @function Mat4(0).getForward
|
||||
* @param {Mat4} m
|
||||
* @returns {Vec3}
|
||||
* @param {Mat4} m - The matrix.
|
||||
* @returns {Vec3} The negative z-axis rotated by the rotation in the matrix.
|
||||
* @example <caption>Demonstrate that the "forward" direction is the negative z-axis.</caption>
|
||||
* var rot = Quat.IDENTITY;
|
||||
* var trans = Vec3.ZERO;
|
||||
* var matrix = Mat4.createFromRotAndTrans(rot, trans);
|
||||
* var forward = Mat4.getForward(matrix);
|
||||
* print("Forward: " + JSON.stringify(forward));
|
||||
* // Forward: {"x":0,"y":0,"z":-1}
|
||||
*/
|
||||
glm::vec3 getForward(const glm::mat4& m) const;
|
||||
|
||||
/**jsdoc
|
||||
* Gets the "right" direction that the camera would have if its orientation was set to the rotation contained in a matrix.
|
||||
* The High Fidelity camera has axes x = right, y = up, -z = forward.
|
||||
* @function Mat4(0).getRight
|
||||
* @param {Mat4} m
|
||||
* @returns {Vec3}
|
||||
* @param {Mat4} m - The matrix.
|
||||
* @returns {Vec3} The x-axis rotated by the rotation in the matrix.
|
||||
*/
|
||||
glm::vec3 getRight(const glm::mat4& m) const;
|
||||
|
||||
/**jsdoc
|
||||
* Gets the "up" direction that the camera would have if its orientation was set to the rotation contained in a matrix. The
|
||||
* High Fidelity camera has axes x = right, y = up, -z = forward.
|
||||
* @function Mat4(0).getUp
|
||||
* @param {Mat4} m
|
||||
* @returns {Vec3}
|
||||
* @param {Mat4} m - The matrix.
|
||||
* @returns {Vec3} The y-axis rotated by the rotation in the matrix.
|
||||
*/
|
||||
glm::vec3 getUp(const glm::mat4& m) const;
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Prints a matrix to the program log as a label followed by the matrix's values.
|
||||
* @function Mat4(0).print
|
||||
* @param {string} label
|
||||
* @param {Mat4} m
|
||||
* @param {boolean} [transpose=false]
|
||||
* @param {string} label - The label to print.
|
||||
* @param {Mat4} m - The matrix to print.
|
||||
* @param {boolean} [transpose=false] - <code>true</code> to transpose the matrix before printing (so that it prints the
|
||||
* matrix's rows), <code>false</code> to not transpose the matrix (so that it prints the matrix's columns).
|
||||
* @example <caption>Two ways of printing a label and matrix value.</caption>
|
||||
* var scale = Vec3.multiply(2, Vec3.ONE);
|
||||
* var rot = Quat.fromPitchYawRollDegrees(30, 45, 60);
|
||||
* var trans = { x: 10, y: 11, z: 12 };
|
||||
* var matrix = Mat4.createFromScaleRotAndTrans(scale, rot, trans);
|
||||
*
|
||||
* Mat4.print("Matrix:", matrix);
|
||||
* // Matrix: dmat4x4((0.707107, 1.224745, -1.414214, 0.000000),
|
||||
* // (-1.146447, 1.478398, 0.707107, 0.000000),
|
||||
* // (1.478398, 0.560660, 1.224745, 0.000000),
|
||||
* // (10.000000, 11.000000, 12.000000, 1.000000))
|
||||
*
|
||||
* print("Matrix: " + JSON.stringify(matrix));
|
||||
* // Matrix: {"r0c0":0.7071067094802856,"r1c0":1.2247446775436401,"r2c0":-1.4142136573791504,"r3c0":0,
|
||||
* // "r0c1": -1.1464465856552124, "r1c1": 1.4783978462219238, "r2c1": 0.7071066498756409, "r3c1": 0,
|
||||
* // "r0c2": 1.4783978462219238, "r1c2": 0.5606603026390076, "r2c2": 1.2247447967529297, "r3c2": 0,
|
||||
* // "r0c3": 10, "r1c3": 11, "r2c3": 12, "r3c3": 1}
|
||||
*/
|
||||
void print(const QString& label, const glm::mat4& m, bool transpose = false) const;
|
||||
};
|
||||
|
|
|
@ -9,14 +9,25 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var IDENTITY = {r0c0: 1, r0c1: 0, r0c2: 0, r0c3: 0,
|
||||
r1c0: 0, r1c1: 1, r1c2: 0, r1c3: 0,
|
||||
r2c0: 0, r2c1: 0, r2c2: 1, r2c3: 0,
|
||||
r3c0: 0, r3c1: 0, r3c2: 0, r3c3: 1};
|
||||
var X = {x: 1, y: 0, z: 0};
|
||||
var Y = {x: 0, y: 1, z: 0};
|
||||
var Z = {x: 0, y: 0, z: 1};
|
||||
|
||||
var IDENTITY = {
|
||||
r0c0: 1, r0c1: 0, r0c2: 0, r0c3: 0,
|
||||
r1c0: 0, r1c1: 1, r1c2: 0, r1c3: 0,
|
||||
r2c0: 0, r2c1: 0, r2c2: 1, r2c3: 0,
|
||||
r3c0: 0, r3c1: 0, r3c2: 0, r3c3: 1
|
||||
};
|
||||
|
||||
var ROT_ZERO = {x: 0, y: 0, z: 0, w: 1};
|
||||
var ROT_Y_180 = {x: 0, y: 1, z: 0, w: 0};
|
||||
|
||||
var DEG_45 = Math.PI / 4;
|
||||
var ROT_X_45 = Quat.angleAxis(DEG_45, X);
|
||||
var ROT_Y_45 = Quat.angleAxis(DEG_45, Y);
|
||||
var ROT_Z_45 = Quat.angleAxis(DEG_45, Z);
|
||||
|
||||
var ONE = {x: 1, y: 1, z: 1};
|
||||
var ZERO = {x: 0, y: 0, z: 0};
|
||||
var ONE_TWO_THREE = {x: 1, y: 2, z: 3};
|
||||
|
@ -24,6 +35,7 @@ var ONE_HALF = {x: 0.5, y: 0.5, z: 0.5};
|
|||
|
||||
var EPSILON = 0.000001;
|
||||
|
||||
|
||||
function mat4FuzzyEqual(a, b) {
|
||||
var r, c;
|
||||
for (r = 0; r < 4; r++) {
|
||||
|
@ -141,12 +153,45 @@ function testInverse() {
|
|||
assert(mat4FuzzyEqual(IDENTITY, Mat4.multiply(test2, Mat4.inverse(test2))));
|
||||
}
|
||||
|
||||
function testForward() {
|
||||
var test0 = IDENTITY;
|
||||
assert(mat4FuzzyEqual({x: 0, y: 0, z: -1}, Mat4.getForward(test0)));
|
||||
function columnsFromQuat(q) {
|
||||
var axes = [Vec3.multiplyQbyV(q, X), Vec3.multiplyQbyV(q, Y), Vec3.multiplyQbyV(q, Z)];
|
||||
axes[0].w = 0;
|
||||
axes[1].w = 0;
|
||||
axes[2].w = 0;
|
||||
axes[3] = {x: 0, y: 0, z: 0, w: 1};
|
||||
return axes;
|
||||
}
|
||||
|
||||
var test1 = Mat4.createFromScaleRotAndTrans(ONE_HALF, ROT_Y_180, ONE_TWO_THREE);
|
||||
assert(mat4FuzzyEqual({x: 0, y: 0, z: 1}, Mat4.getForward(test1)));
|
||||
function matrixFromColumns(cols) {
|
||||
return Mat4.createFromColumns(cols[0], cols[1], cols[2], cols[3]);
|
||||
}
|
||||
|
||||
function testMatForwardRightUpFromQuat(q) {
|
||||
var cols = columnsFromQuat(q);
|
||||
var mat = matrixFromColumns(cols);
|
||||
|
||||
assert(vec3FuzzyEqual(Mat4.getForward(mat), Vec3.multiply(cols[2], -1)));
|
||||
assert(vec3FuzzyEqual(Mat4.getForward(mat), Quat.getForward(q)));
|
||||
|
||||
assert(vec3FuzzyEqual(Mat4.getRight(mat), cols[0]));
|
||||
assert(vec3FuzzyEqual(Mat4.getRight(mat), Quat.getRight(q)));
|
||||
|
||||
assert(vec3FuzzyEqual(Mat4.getUp(mat), cols[1]));
|
||||
assert(vec3FuzzyEqual(Mat4.getUp(mat), Quat.getUp(q)));
|
||||
}
|
||||
|
||||
function testForwardRightUp() {
|
||||
|
||||
// test several variations of rotations
|
||||
testMatForwardRightUpFromQuat(ROT_X_45);
|
||||
testMatForwardRightUpFromQuat(ROT_Y_45);
|
||||
testMatForwardRightUpFromQuat(ROT_Z_45);
|
||||
testMatForwardRightUpFromQuat(Quat.multiply(ROT_X_45, ROT_Y_45));
|
||||
testMatForwardRightUpFromQuat(Quat.multiply(ROT_Y_45, ROT_X_45));
|
||||
testMatForwardRightUpFromQuat(Quat.multiply(ROT_X_45, ROT_Z_45));
|
||||
testMatForwardRightUpFromQuat(Quat.multiply(ROT_Z_45, ROT_X_45));
|
||||
testMatForwardRightUpFromQuat(Quat.multiply(ROT_X_45, ROT_Z_45));
|
||||
testMatForwardRightUpFromQuat(Quat.multiply(ROT_Z_45, ROT_X_45));
|
||||
}
|
||||
|
||||
function testMat4() {
|
||||
|
@ -157,7 +202,7 @@ function testMat4() {
|
|||
testTransformPoint();
|
||||
testTransformVector();
|
||||
testInverse();
|
||||
testForward();
|
||||
testForwardRightUp();
|
||||
|
||||
print("MAT4 TEST complete! (" + (testCount - failureCount) + "/" + testCount + ") tests passed!");
|
||||
}
|
||||
|
|
|
@ -296,7 +296,7 @@ function updateOutputDeviceMutedOverlay(isMuted) {
|
|||
props.y = Window.innerHeight / 2 - overlayDims / 2;
|
||||
|
||||
var outputDeviceMutedOverlayBottomY = props.y + overlayDims;
|
||||
var inputDeviceMutedOverlayTopY = getInputDeviceMutedOverlayTopY();
|
||||
var inputDeviceMutedOverlayTopY = INPUT_DEVICE_MUTED_MARGIN_TOP_PX;
|
||||
if (outputDeviceMutedOverlayBottomY + OUTPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX > inputDeviceMutedOverlayTopY) {
|
||||
overlayDims = 2 * (inputDeviceMutedOverlayTopY - Window.innerHeight / 2 - OUTPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX);
|
||||
}
|
||||
|
@ -473,15 +473,11 @@ function maybeDeleteInputDeviceMutedOverlay() {
|
|||
}
|
||||
|
||||
|
||||
function getInputDeviceMutedOverlayTopY() {
|
||||
return (Window.innerHeight - INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_Y_PX - INPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX);
|
||||
}
|
||||
|
||||
|
||||
var inputDeviceMutedOverlay = false;
|
||||
var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_X_PX = 353;
|
||||
var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_Y_PX = 95;
|
||||
var INPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX = 20 + TOP_BAR_HEIGHT_PX;
|
||||
var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_X_PX = 237;
|
||||
var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_Y_PX = 64;
|
||||
var INPUT_DEVICE_MUTED_MARGIN_LEFT_PX = 20;
|
||||
var INPUT_DEVICE_MUTED_MARGIN_TOP_PX = 20;
|
||||
function updateInputDeviceMutedOverlay(isMuted) {
|
||||
if (isMuted) {
|
||||
var props = {
|
||||
|
@ -490,8 +486,8 @@ function updateInputDeviceMutedOverlay(isMuted) {
|
|||
};
|
||||
props.width = INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_X_PX;
|
||||
props.height = INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_Y_PX;
|
||||
props.x = Window.innerWidth / 2 - INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_X_PX / 2;
|
||||
props.y = getInputDeviceMutedOverlayTopY();
|
||||
props.x = INPUT_DEVICE_MUTED_MARGIN_LEFT_PX;
|
||||
props.y = INPUT_DEVICE_MUTED_MARGIN_TOP_PX;
|
||||
if (inputDeviceMutedOverlay) {
|
||||
Overlays.editOverlay(inputDeviceMutedOverlay, props);
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue