mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 17:01:06 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into orange
This commit is contained in:
commit
c6a081fb46
905 changed files with 11408 additions and 3752 deletions
|
@ -386,8 +386,7 @@ void Agent::sendAvatarBillboardPacket() {
|
||||||
void Agent::processAgentAvatarAndAudio(float deltaTime) {
|
void Agent::processAgentAvatarAndAudio(float deltaTime) {
|
||||||
if (!_scriptEngine->isFinished() && _isAvatar) {
|
if (!_scriptEngine->isFinished() && _isAvatar) {
|
||||||
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||||
const int SCRIPT_AUDIO_BUFFER_SAMPLES = floor(((SCRIPT_DATA_CALLBACK_USECS * AudioConstants::SAMPLE_RATE)
|
const int SCRIPT_AUDIO_BUFFER_SAMPLES = AudioConstants::SAMPLE_RATE / SCRIPT_FPS + 0.5;
|
||||||
/ (1000 * 1000)) + 0.5);
|
|
||||||
const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t);
|
const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t);
|
||||||
|
|
||||||
QByteArray avatarByteArray = scriptedAvatar->toByteArray(true, randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO);
|
QByteArray avatarByteArray = scriptedAvatar->toByteArray(true, randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO);
|
||||||
|
|
|
@ -23,7 +23,7 @@ AssignmentAction::AssignmentAction(EntityActionType type, const QUuid& id, Entit
|
||||||
AssignmentAction::~AssignmentAction() {
|
AssignmentAction::~AssignmentAction() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssignmentAction::removeFromSimulation(EntitySimulation* simulation) const {
|
void AssignmentAction::removeFromSimulation(EntitySimulationPointer simulation) const {
|
||||||
withReadLock([&]{
|
withReadLock([&]{
|
||||||
simulation->removeAction(_id);
|
simulation->removeAction(_id);
|
||||||
simulation->applyActionChanges();
|
simulation->applyActionChanges();
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
AssignmentAction(EntityActionType type, const QUuid& id, EntityItemPointer ownerEntity);
|
AssignmentAction(EntityActionType type, const QUuid& id, EntityItemPointer ownerEntity);
|
||||||
virtual ~AssignmentAction();
|
virtual ~AssignmentAction();
|
||||||
|
|
||||||
virtual void removeFromSimulation(EntitySimulation* simulation) const;
|
virtual void removeFromSimulation(EntitySimulationPointer simulation) const;
|
||||||
virtual EntityItemWeakPointer getOwnerEntity() const { return _ownerEntity; }
|
virtual EntityItemWeakPointer getOwnerEntity() const { return _ownerEntity; }
|
||||||
virtual void setOwnerEntity(const EntityItemPointer ownerEntity) { _ownerEntity = ownerEntity; }
|
virtual void setOwnerEntity(const EntityItemPointer ownerEntity) { _ownerEntity = ownerEntity; }
|
||||||
virtual bool updateArguments(QVariantMap arguments);
|
virtual bool updateArguments(QVariantMap arguments);
|
||||||
|
|
|
@ -56,7 +56,7 @@ OctreePointer EntityServer::createTree() {
|
||||||
tree->createRootElement();
|
tree->createRootElement();
|
||||||
tree->addNewlyCreatedHook(this);
|
tree->addNewlyCreatedHook(this);
|
||||||
if (!_entitySimulation) {
|
if (!_entitySimulation) {
|
||||||
SimpleEntitySimulation* simpleSimulation = new SimpleEntitySimulation();
|
SimpleEntitySimulationPointer simpleSimulation { new SimpleEntitySimulation() };
|
||||||
simpleSimulation->setEntityTree(tree);
|
simpleSimulation->setEntityTree(tree);
|
||||||
tree->setSimulation(simpleSimulation);
|
tree->setSimulation(simpleSimulation);
|
||||||
_entitySimulation = simpleSimulation;
|
_entitySimulation = simpleSimulation;
|
||||||
|
|
|
@ -28,6 +28,8 @@ struct ViewerSendingStats {
|
||||||
};
|
};
|
||||||
|
|
||||||
class SimpleEntitySimulation;
|
class SimpleEntitySimulation;
|
||||||
|
using SimpleEntitySimulationPointer = std::shared_ptr<SimpleEntitySimulation>;
|
||||||
|
|
||||||
|
|
||||||
class EntityServer : public OctreeServer, public NewlyCreatedEntityHook {
|
class EntityServer : public OctreeServer, public NewlyCreatedEntityHook {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -69,7 +71,7 @@ private slots:
|
||||||
void handleEntityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
void handleEntityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SimpleEntitySimulation* _entitySimulation;
|
SimpleEntitySimulationPointer _entitySimulation;
|
||||||
QTimer* _pruneDeletedEntitiesTimer = nullptr;
|
QTimer* _pruneDeletedEntitiesTimer = nullptr;
|
||||||
|
|
||||||
QReadWriteLock _viewerSendingStatsLock;
|
QReadWriteLock _viewerSendingStatsLock;
|
||||||
|
|
|
@ -141,6 +141,16 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int by
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OctreeQueryNode::copyCurrentViewFrustum(ViewFrustum& viewOut) const {
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
viewOut = _currentViewFrustum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OctreeQueryNode::copyLastKnownViewFrustum(ViewFrustum& viewOut) const {
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
viewOut = _lastKnownViewFrustum;
|
||||||
|
}
|
||||||
|
|
||||||
bool OctreeQueryNode::updateCurrentViewFrustum() {
|
bool OctreeQueryNode::updateCurrentViewFrustum() {
|
||||||
// if shutting down, return immediately
|
// if shutting down, return immediately
|
||||||
if (_isShuttingDown) {
|
if (_isShuttingDown) {
|
||||||
|
@ -171,11 +181,13 @@ bool OctreeQueryNode::updateCurrentViewFrustum() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if there has been a change, then recalculate
|
{ // if there has been a change, then recalculate
|
||||||
if (!newestViewFrustum.isVerySimilar(_currentViewFrustum)) {
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
_currentViewFrustum = newestViewFrustum;
|
if (!newestViewFrustum.isVerySimilar(_currentViewFrustum)) {
|
||||||
_currentViewFrustum.calculate();
|
_currentViewFrustum = newestViewFrustum;
|
||||||
currentViewFrustumChanged = true;
|
_currentViewFrustum.calculate();
|
||||||
|
currentViewFrustumChanged = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also check for LOD changes from the client
|
// Also check for LOD changes from the client
|
||||||
|
@ -219,11 +231,14 @@ void OctreeQueryNode::updateLastKnownViewFrustum() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool frustumChanges = !_lastKnownViewFrustum.isVerySimilar(_currentViewFrustum);
|
{
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
bool frustumChanges = !_lastKnownViewFrustum.isVerySimilar(_currentViewFrustum);
|
||||||
|
|
||||||
if (frustumChanges) {
|
if (frustumChanges) {
|
||||||
// save our currentViewFrustum into our lastKnownViewFrustum
|
// save our currentViewFrustum into our lastKnownViewFrustum
|
||||||
_lastKnownViewFrustum = _currentViewFrustum;
|
_lastKnownViewFrustum = _currentViewFrustum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// save that we know the view has been sent.
|
// save that we know the view has been sent.
|
||||||
|
@ -237,15 +252,13 @@ bool OctreeQueryNode::moveShouldDump() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
glm::vec3 oldPosition = _lastKnownViewFrustum.getPosition();
|
glm::vec3 oldPosition = _lastKnownViewFrustum.getPosition();
|
||||||
glm::vec3 newPosition = _currentViewFrustum.getPosition();
|
glm::vec3 newPosition = _currentViewFrustum.getPosition();
|
||||||
|
|
||||||
// theoretically we could make this slightly larger but relative to avatar scale.
|
// theoretically we could make this slightly larger but relative to avatar scale.
|
||||||
const float MAXIMUM_MOVE_WITHOUT_DUMP = 0.0f;
|
const float MAXIMUM_MOVE_WITHOUT_DUMP = 0.0f;
|
||||||
if (glm::distance(newPosition, oldPosition) > MAXIMUM_MOVE_WITHOUT_DUMP) {
|
return glm::distance(newPosition, oldPosition) > MAXIMUM_MOVE_WITHOUT_DUMP;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeQueryNode::dumpOutOfView() {
|
void OctreeQueryNode::dumpOutOfView() {
|
||||||
|
@ -257,8 +270,10 @@ void OctreeQueryNode::dumpOutOfView() {
|
||||||
int stillInView = 0;
|
int stillInView = 0;
|
||||||
int outOfView = 0;
|
int outOfView = 0;
|
||||||
OctreeElementBag tempBag;
|
OctreeElementBag tempBag;
|
||||||
|
ViewFrustum viewCopy;
|
||||||
|
copyCurrentViewFrustum(viewCopy);
|
||||||
while (OctreeElementPointer elementToCheck = elementBag.extract()) {
|
while (OctreeElementPointer elementToCheck = elementBag.extract()) {
|
||||||
if (elementToCheck->isInView(_currentViewFrustum)) {
|
if (elementToCheck->isInView(viewCopy)) {
|
||||||
tempBag.insert(elementToCheck);
|
tempBag.insert(elementToCheck);
|
||||||
stillInView++;
|
stillInView++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -267,7 +282,7 @@ void OctreeQueryNode::dumpOutOfView() {
|
||||||
}
|
}
|
||||||
if (stillInView > 0) {
|
if (stillInView > 0) {
|
||||||
while (OctreeElementPointer elementToKeepInBag = tempBag.extract()) {
|
while (OctreeElementPointer elementToKeepInBag = tempBag.extract()) {
|
||||||
if (elementToKeepInBag->isInView(_currentViewFrustum)) {
|
if (elementToKeepInBag->isInView(viewCopy)) {
|
||||||
elementBag.insert(elementToKeepInBag);
|
elementBag.insert(elementToKeepInBag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
|
|
||||||
bool packetIsDuplicate() const;
|
bool packetIsDuplicate() const;
|
||||||
bool shouldSuppressDuplicatePacket();
|
bool shouldSuppressDuplicatePacket();
|
||||||
|
|
||||||
unsigned int getAvailable() const { return _octreePacket->bytesAvailableForWrite(); }
|
unsigned int getAvailable() const { return _octreePacket->bytesAvailableForWrite(); }
|
||||||
int getMaxSearchLevel() const { return _maxSearchLevel; }
|
int getMaxSearchLevel() const { return _maxSearchLevel; }
|
||||||
void resetMaxSearchLevel() { _maxSearchLevel = 1; }
|
void resetMaxSearchLevel() { _maxSearchLevel = 1; }
|
||||||
|
@ -56,8 +56,8 @@ public:
|
||||||
OctreeElementBag elementBag;
|
OctreeElementBag elementBag;
|
||||||
OctreeElementExtraEncodeData extraEncodeData;
|
OctreeElementExtraEncodeData extraEncodeData;
|
||||||
|
|
||||||
ViewFrustum& getCurrentViewFrustum() { return _currentViewFrustum; }
|
void copyCurrentViewFrustum(ViewFrustum& viewOut) const;
|
||||||
ViewFrustum& getLastKnownViewFrustum() { return _lastKnownViewFrustum; }
|
void copyLastKnownViewFrustum(ViewFrustum& viewOut) const;
|
||||||
|
|
||||||
// These are not classic setters because they are calculating and maintaining state
|
// These are not classic setters because they are calculating and maintaining state
|
||||||
// which is set asynchronously through the network receive
|
// which is set asynchronously through the network receive
|
||||||
|
@ -114,6 +114,8 @@ private:
|
||||||
|
|
||||||
int _maxSearchLevel { 1 };
|
int _maxSearchLevel { 1 };
|
||||||
int _maxLevelReachedInLastSearch { 1 };
|
int _maxLevelReachedInLastSearch { 1 };
|
||||||
|
|
||||||
|
mutable QMutex _viewMutex { QMutex::Recursive };
|
||||||
ViewFrustum _currentViewFrustum;
|
ViewFrustum _currentViewFrustum;
|
||||||
ViewFrustum _lastKnownViewFrustum;
|
ViewFrustum _lastKnownViewFrustum;
|
||||||
quint64 _lastTimeBagEmpty { 0 };
|
quint64 _lastTimeBagEmpty { 0 };
|
||||||
|
@ -139,7 +141,7 @@ private:
|
||||||
QQueue<OCTREE_PACKET_SEQUENCE> _nackedSequenceNumbers;
|
QQueue<OCTREE_PACKET_SEQUENCE> _nackedSequenceNumbers;
|
||||||
|
|
||||||
quint64 _sceneSendStartTime = 0;
|
quint64 _sceneSendStartTime = 0;
|
||||||
|
|
||||||
std::array<char, udt::MAX_PACKET_SIZE> _lastOctreePayload;
|
std::array<char, udt::MAX_PACKET_SIZE> _lastOctreePayload;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
#include <udt/PacketHeaders.h>
|
#include <udt/PacketHeaders.h>
|
||||||
|
@ -101,13 +104,16 @@ bool OctreeSendThread::process() {
|
||||||
int elapsed = (usecTimestampNow() - start);
|
int elapsed = (usecTimestampNow() - start);
|
||||||
int usecToSleep = OCTREE_SEND_INTERVAL_USECS - elapsed;
|
int usecToSleep = OCTREE_SEND_INTERVAL_USECS - elapsed;
|
||||||
|
|
||||||
if (usecToSleep > 0) {
|
if (usecToSleep <= 0) {
|
||||||
PerformanceWarning warn(false,"OctreeSendThread... usleep()",false,&_usleepTime,&_usleepCalls);
|
|
||||||
usleep(usecToSleep);
|
|
||||||
} else {
|
|
||||||
const int MIN_USEC_TO_SLEEP = 1;
|
const int MIN_USEC_TO_SLEEP = 1;
|
||||||
usleep(MIN_USEC_TO_SLEEP);
|
usecToSleep = MIN_USEC_TO_SLEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
PerformanceWarning warn(false,"OctreeSendThread... usleep()",false,&_usleepTime,&_usleepCalls);
|
||||||
|
std::this_thread::sleep_for(std::chrono::microseconds(usecToSleep));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return isStillRunning(); // keep running till they terminate us
|
return isStillRunning(); // keep running till they terminate us
|
||||||
|
@ -332,8 +338,6 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode*
|
||||||
|
|
||||||
_packetData.changeSettings(true, targetSize); // FIXME - eventually support only compressed packets
|
_packetData.changeSettings(true, targetSize); // FIXME - eventually support only compressed packets
|
||||||
|
|
||||||
const ViewFrustum* lastViewFrustum = viewFrustumChanged ? &nodeData->getLastKnownViewFrustum() : NULL;
|
|
||||||
|
|
||||||
// If the current view frustum has changed OR we have nothing to send, then search against
|
// If the current view frustum has changed OR we have nothing to send, then search against
|
||||||
// the current view frustum for things to send.
|
// the current view frustum for things to send.
|
||||||
if (viewFrustumChanged || nodeData->elementBag.isEmpty()) {
|
if (viewFrustumChanged || nodeData->elementBag.isEmpty()) {
|
||||||
|
@ -411,7 +415,7 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode*
|
||||||
quint64 lockWaitEnd = usecTimestampNow();
|
quint64 lockWaitEnd = usecTimestampNow();
|
||||||
lockWaitElapsedUsec = (float)(lockWaitEnd - lockWaitStart);
|
lockWaitElapsedUsec = (float)(lockWaitEnd - lockWaitStart);
|
||||||
quint64 encodeStart = usecTimestampNow();
|
quint64 encodeStart = usecTimestampNow();
|
||||||
|
|
||||||
OctreeElementPointer subTree = nodeData->elementBag.extract();
|
OctreeElementPointer subTree = nodeData->elementBag.extract();
|
||||||
if (!subTree) {
|
if (!subTree) {
|
||||||
return;
|
return;
|
||||||
|
@ -420,18 +424,22 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode*
|
||||||
float octreeSizeScale = nodeData->getOctreeSizeScale();
|
float octreeSizeScale = nodeData->getOctreeSizeScale();
|
||||||
int boundaryLevelAdjustClient = nodeData->getBoundaryLevelAdjust();
|
int boundaryLevelAdjustClient = nodeData->getBoundaryLevelAdjust();
|
||||||
|
|
||||||
int boundaryLevelAdjust = boundaryLevelAdjustClient +
|
int boundaryLevelAdjust = boundaryLevelAdjustClient +
|
||||||
(viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST);
|
(viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST);
|
||||||
|
|
||||||
EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(),
|
EncodeBitstreamParams params(INT_MAX, WANT_EXISTS_BITS, DONT_CHOP,
|
||||||
WANT_EXISTS_BITS, DONT_CHOP, viewFrustumChanged, lastViewFrustum,
|
viewFrustumChanged,
|
||||||
boundaryLevelAdjust, octreeSizeScale,
|
boundaryLevelAdjust, octreeSizeScale,
|
||||||
nodeData->getLastTimeBagEmpty(),
|
nodeData->getLastTimeBagEmpty(),
|
||||||
isFullScene, &nodeData->stats, _myServer->getJurisdiction(),
|
isFullScene, &nodeData->stats, _myServer->getJurisdiction(),
|
||||||
&nodeData->extraEncodeData);
|
&nodeData->extraEncodeData);
|
||||||
|
nodeData->copyCurrentViewFrustum(params.viewFrustum);
|
||||||
|
if (viewFrustumChanged) {
|
||||||
|
nodeData->copyLastKnownViewFrustum(params.lastViewFrustum);
|
||||||
|
}
|
||||||
|
|
||||||
// Our trackSend() function is implemented by the server subclass, and will be called back
|
// Our trackSend() function is implemented by the server subclass, and will be called back
|
||||||
// during the encodeTreeBitstream() as new entities/data elements are sent
|
// during the encodeTreeBitstream() as new entities/data elements are sent
|
||||||
params.trackSend = [this, node](const QUuid& dataID, quint64 dataEdited) {
|
params.trackSend = [this, node](const QUuid& dataID, quint64 dataEdited) {
|
||||||
_myServer->trackSend(dataID, dataEdited, node->getUUID());
|
_myServer->trackSend(dataID, dataEdited, node->getUUID());
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,7 +19,7 @@ macro(GENERATE_INSTALLERS)
|
||||||
set(CPACK_PACKAGE_NAME ${_DISPLAY_NAME})
|
set(CPACK_PACKAGE_NAME ${_DISPLAY_NAME})
|
||||||
set(CPACK_PACKAGE_VENDOR "High Fidelity")
|
set(CPACK_PACKAGE_VENDOR "High Fidelity")
|
||||||
set(CPACK_PACKAGE_VERSION ${BUILD_VERSION})
|
set(CPACK_PACKAGE_VERSION ${BUILD_VERSION})
|
||||||
set(CPACK_PACKAGE_FILE_NAME "HighFidelity-Alpha-${BUILD_VERSION}")
|
set(CPACK_PACKAGE_FILE_NAME "HighFidelity-Beta-${BUILD_VERSION}")
|
||||||
set(CPACK_NSIS_DISPLAY_NAME ${_DISPLAY_NAME})
|
set(CPACK_NSIS_DISPLAY_NAME ${_DISPLAY_NAME})
|
||||||
set(CPACK_NSIS_PACKAGE_NAME ${_DISPLAY_NAME})
|
set(CPACK_NSIS_PACKAGE_NAME ${_DISPLAY_NAME})
|
||||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${_DISPLAY_NAME})
|
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${_DISPLAY_NAME})
|
||||||
|
|
148
examples/clap.js
148
examples/clap.js
|
@ -1,148 +0,0 @@
|
||||||
//
|
|
||||||
// clap.js
|
|
||||||
// examples
|
|
||||||
//
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// This sample script watches your hydra hands and makes clapping sound when they come close together fast,
|
|
||||||
// and also watches for the 'shift' key and claps when that key is pressed. Clapping multiple times by pressing
|
|
||||||
// the shift key again makes the animation and sound match your pace of clapping.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
|
||||||
|
|
||||||
var clapAnimation = HIFI_PUBLIC_BUCKET + "animations/ClapAnimations/ClapHands_Standing.fbx";
|
|
||||||
var ANIMATION_FRAMES_PER_CLAP = 10.0;
|
|
||||||
var startEndFrames = [];
|
|
||||||
startEndFrames.push({ start: 0, end: 10});
|
|
||||||
startEndFrames.push({ start: 10, end: 20});
|
|
||||||
startEndFrames.push({ start: 20, end: 30});
|
|
||||||
startEndFrames.push({ start: 30, end: 40});
|
|
||||||
startEndFrames.push({ start: 41, end: 51});
|
|
||||||
startEndFrames.push({ start: 53, end: 0});
|
|
||||||
|
|
||||||
var lastClapFrame = 0;
|
|
||||||
var lastAnimFrame = 0;
|
|
||||||
|
|
||||||
var claps = [];
|
|
||||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap1Rvb.wav"));
|
|
||||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap2Rvb.wav"));
|
|
||||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap3Rvb.wav"));
|
|
||||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap4Rvb.wav"));
|
|
||||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap5Rvb.wav"));
|
|
||||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap6Rvb.wav"));
|
|
||||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap7Rvb.wav"));
|
|
||||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap8Rvb.wav"));
|
|
||||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap9Rvb.wav"));
|
|
||||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap10Rvb.wav"));
|
|
||||||
var numberOfSounds = claps.length;
|
|
||||||
|
|
||||||
var clappingNow = false;
|
|
||||||
var collectedClicks = 0;
|
|
||||||
|
|
||||||
var clickStartTime, clickEndTime;
|
|
||||||
var clickClappingNow = false;
|
|
||||||
var CLAP_START_RATE = 15.0;
|
|
||||||
var clapRate = CLAP_START_RATE;
|
|
||||||
var startedTimer = false;
|
|
||||||
|
|
||||||
function maybePlaySound(deltaTime) {
|
|
||||||
// Set the location and other info for the sound to play
|
|
||||||
|
|
||||||
var animationDetails = MyAvatar.getAnimationDetails(clapAnimation);
|
|
||||||
|
|
||||||
var frame = Math.floor(animationDetails.frameIndex);
|
|
||||||
|
|
||||||
if (frame != lastAnimFrame) {
|
|
||||||
lastAnimFrame = frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < startEndFrames.length; i++) {
|
|
||||||
if (frame == startEndFrames[i].start && (frame != lastClapFrame)) {
|
|
||||||
playClap(1.0, Camera.getPosition());
|
|
||||||
lastClapFrame = frame;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var palm1Position = MyAvatar.getLeftPalmPosition();
|
|
||||||
var palm2Position = MyAvatar.getRightPalmPosition();
|
|
||||||
var distanceBetween = Vec3.length(Vec3.subtract(palm1Position, palm2Position));
|
|
||||||
|
|
||||||
var palm1Velocity = Controller.getPoseValue(Controller.Standard.LeftHand).velocity;
|
|
||||||
var palm2Velocity = Controller.getPoseValue(Controller.Standard.RightHand).velocity;
|
|
||||||
var closingVelocity = Vec3.length(Vec3.subtract(palm1Velocity, palm2Velocity));
|
|
||||||
|
|
||||||
const CLAP_SPEED = 0.7;
|
|
||||||
const CLAP_DISTANCE = 0.15;
|
|
||||||
|
|
||||||
if ((closingVelocity > CLAP_SPEED) && (distanceBetween < CLAP_DISTANCE) && !clappingNow) {
|
|
||||||
var volume = closingVelocity / 2.0;
|
|
||||||
if (volume > 1.0) volume = 1.0;
|
|
||||||
playClap(volume, palm1Position);
|
|
||||||
clappingNow = true;
|
|
||||||
} else if (clappingNow && (distanceBetween > CLAP_DISTANCE * 1.2)) {
|
|
||||||
clappingNow = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function playClap(volume, position) {
|
|
||||||
var clip = Math.floor(Math.random() * numberOfSounds);
|
|
||||||
Audio.playSound(claps[clip], {
|
|
||||||
position: position,
|
|
||||||
volume: volume
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var FASTEST_CLAP_INTERVAL = 150.0;
|
|
||||||
var SLOWEST_CLAP_INTERVAL = 750.0;
|
|
||||||
|
|
||||||
Controller.keyPressEvent.connect(function(event) {
|
|
||||||
if(event.text == "SHIFT") {
|
|
||||||
if (!clickClappingNow) {
|
|
||||||
clickClappingNow = true;
|
|
||||||
clickStartTime = new Date();
|
|
||||||
lastClapFrame = 0;
|
|
||||||
} else {
|
|
||||||
// start or adjust clapping speed based on the duration between clicks
|
|
||||||
clickEndTime = new Date();
|
|
||||||
var milliseconds = Math.max(clickEndTime - clickStartTime, FASTEST_CLAP_INTERVAL);
|
|
||||||
clickStartTime = new Date();
|
|
||||||
if (milliseconds < SLOWEST_CLAP_INTERVAL) {
|
|
||||||
clapRate = ANIMATION_FRAMES_PER_CLAP * (1000.0 / milliseconds);
|
|
||||||
playClap(1.0, Camera.getPosition());
|
|
||||||
MyAvatar.stopAnimation(clapAnimation);
|
|
||||||
MyAvatar.startAnimation(clapAnimation, clapRate, 1.0, true, false);
|
|
||||||
}
|
|
||||||
collectedClicks = collectedClicks + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var CLAP_END_WAIT_MSECS = 300;
|
|
||||||
Controller.keyReleaseEvent.connect(function(event) {
|
|
||||||
if (event.text == "SHIFT") {
|
|
||||||
collectedClicks = 0;
|
|
||||||
if (!startedTimer) {
|
|
||||||
collectedClicks = 0;
|
|
||||||
Script.setTimeout(stopClapping, CLAP_END_WAIT_MSECS);
|
|
||||||
startedTimer = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function stopClapping() {
|
|
||||||
if (collectedClicks == 0) {
|
|
||||||
startedTimer = false;
|
|
||||||
MyAvatar.stopAnimation(clapAnimation);
|
|
||||||
clapRate = CLAP_START_RATE;
|
|
||||||
clickClappingNow = false;
|
|
||||||
} else {
|
|
||||||
startedTimer = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect a call back that happens every frame
|
|
||||||
Script.update.connect(maybePlaySound);
|
|
|
@ -1,68 +0,0 @@
|
||||||
|
|
||||||
// cowEntityScript.js
|
|
||||||
// examples/cows
|
|
||||||
//
|
|
||||||
// Created by Eric Levin on 3/25/16
|
|
||||||
// Copyright 2016 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// This entity script handles the logic for untipping a cow after it collides with something
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
Script.include("../libraries/utils.js");
|
|
||||||
|
|
||||||
var _this = this;
|
|
||||||
_this.COLLISION_COOLDOWN_TIME = 5000;
|
|
||||||
|
|
||||||
|
|
||||||
this.preload = function(entityID) {
|
|
||||||
print("EBL Preload!!");
|
|
||||||
_this.entityID = entityID;
|
|
||||||
_this.mooSound = SoundCache.getSound("https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/moo.wav")
|
|
||||||
_this.mooSoundOptions = {volume: 0.7, loop: false};
|
|
||||||
_this.timeSinceLastCollision = 0;
|
|
||||||
_this.shouldUntipCow = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.collisionWithEntity = function(myID, otherID, collisionInfo) {
|
|
||||||
if(_this.shouldUntipCow) {
|
|
||||||
Script.setTimeout(function() {
|
|
||||||
_this.untipCow();
|
|
||||||
_this.shouldUntipCow = true;
|
|
||||||
}, _this.COLLISION_COOLDOWN_TIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
_this.shouldUntipCow = false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
this.untipCow = function() {
|
|
||||||
// keep yaw but reset pitch and roll
|
|
||||||
var cowProps = Entities.getEntityProperties(_this.entityID, ["rotation", "position"]);
|
|
||||||
var eulerRotation = Quat.safeEulerAngles(cowProps.rotation);
|
|
||||||
eulerRotation.x = 0;
|
|
||||||
eulerRotation.z = 0;
|
|
||||||
var newRotation = Quat.fromVec3Degrees(eulerRotation);
|
|
||||||
Entities.editEntity(_this.entityID, {
|
|
||||||
rotation: newRotation,
|
|
||||||
velocity: {x: 0, y: 0, z: 0},
|
|
||||||
angularVelocity: {x: 0, y: 0, z:0}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
_this.mooSoundOptions.position = cowProps.position;
|
|
||||||
if (!_this.soundInjector) {
|
|
||||||
_this.soundInjector = Audio.playSound(_this.mooSound, _this.mooSoundOptions);
|
|
||||||
} else {
|
|
||||||
_this.soundInjector.setOptions(_this.mooSoundOptions);
|
|
||||||
_this.soundInjector.restart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
|
@ -1,53 +0,0 @@
|
||||||
|
|
||||||
// cowSpawner.js
|
|
||||||
// examples/cows
|
|
||||||
//
|
|
||||||
// Created by Eric Levin on 3/25/16
|
|
||||||
// Copyright 2016 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// This spawns a cow which will untip itself
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
var orientation = MyAvatar.orientation;
|
|
||||||
orientation = Quat.safeEulerAngles(orientation);
|
|
||||||
orientation.x = 0;
|
|
||||||
orientation = Quat.fromVec3Degrees(orientation);
|
|
||||||
var center = Vec3.sum(MyAvatar.getHeadPosition(), Vec3.multiply(2, Quat.getFront(orientation)));
|
|
||||||
|
|
||||||
|
|
||||||
var SCRIPT_URL = Script.resolvePath("cowEntityScript.js?");
|
|
||||||
var cow = Entities.addEntity({
|
|
||||||
type: "Model",
|
|
||||||
modelURL: "http://hifi-content.s3.amazonaws.com/DomainContent/production/cow/newMooCow.fbx",
|
|
||||||
name: "playa_model_throwinCow",
|
|
||||||
position: center,
|
|
||||||
animation: {
|
|
||||||
currentFrame: 278,
|
|
||||||
running: true,
|
|
||||||
url: "http://hifi-content.s3.amazonaws.com/DomainContent/Junkyard/Playa/newMooCow.fbx"
|
|
||||||
},
|
|
||||||
dimensions: {
|
|
||||||
x: 0.739,
|
|
||||||
y: 1.613,
|
|
||||||
z: 2.529
|
|
||||||
},
|
|
||||||
dynamic: true,
|
|
||||||
gravity: {
|
|
||||||
x: 0,
|
|
||||||
y: -5,
|
|
||||||
z: 0
|
|
||||||
},
|
|
||||||
shapeType: "box",
|
|
||||||
script: SCRIPT_URL,
|
|
||||||
userData: "{\"grabbableKey\":{\"grabbable\":true}}"
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function cleanup() {
|
|
||||||
Entities.deleteEntity(cow);
|
|
||||||
}
|
|
||||||
|
|
||||||
Script.scriptEnding.connect(cleanup);
|
|
|
@ -1,22 +0,0 @@
|
||||||
//
|
|
||||||
// defaultScripts.js
|
|
||||||
// examples
|
|
||||||
//
|
|
||||||
// Copyright 2014 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
|
|
||||||
//
|
|
||||||
|
|
||||||
Script.load("away.js");
|
|
||||||
Script.load("progress.js");
|
|
||||||
Script.load("edit.js");
|
|
||||||
Script.load("examples.js");
|
|
||||||
Script.load("selectAudioDevice.js");
|
|
||||||
Script.load("notifications.js");
|
|
||||||
Script.load("controllers/handControllerGrab.js");
|
|
||||||
Script.load("controllers/squeezeHands.js");
|
|
||||||
Script.load("grab.js");
|
|
||||||
Script.load("directory.js");
|
|
||||||
Script.load("dialTone.js");
|
|
||||||
Script.load("depthReticle.js");
|
|
|
@ -1,185 +0,0 @@
|
||||||
// depthReticle.js
|
|
||||||
// examples
|
|
||||||
//
|
|
||||||
// Created by Brad Hefta-Gaub on 2/23/16.
|
|
||||||
// Copyright 2016 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// When used in HMD, this script will make the reticle depth track to any clickable item in view.
|
|
||||||
// This script also handles auto-hiding the reticle after inactivity, as well as having the reticle
|
|
||||||
// seek the look at position upon waking up.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
var APPARENT_2D_OVERLAY_DEPTH = 1.0;
|
|
||||||
var APPARENT_MAXIMUM_DEPTH = 100.0; // this is a depth at which things all seem sufficiently distant
|
|
||||||
var lastDepthCheckTime = Date.now();
|
|
||||||
var desiredDepth = APPARENT_2D_OVERLAY_DEPTH;
|
|
||||||
var TIME_BETWEEN_DEPTH_CHECKS = 100;
|
|
||||||
var MINIMUM_DEPTH_ADJUST = 0.01;
|
|
||||||
var NON_LINEAR_DIVISOR = 2;
|
|
||||||
var MINIMUM_SEEK_DISTANCE = 0.01;
|
|
||||||
|
|
||||||
var lastMouseMoveOrClick = Date.now();
|
|
||||||
var lastMouseX = Reticle.position.x;
|
|
||||||
var lastMouseY = Reticle.position.y;
|
|
||||||
var HIDE_STATIC_MOUSE_AFTER = 3000; // 3 seconds
|
|
||||||
var shouldSeekToLookAt = false;
|
|
||||||
var fastMouseMoves = 0;
|
|
||||||
var averageMouseVelocity = 0;
|
|
||||||
var WEIGHTING = 1/20; // simple moving average over last 20 samples
|
|
||||||
var ONE_MINUS_WEIGHTING = 1 - WEIGHTING;
|
|
||||||
var AVERAGE_MOUSE_VELOCITY_FOR_SEEK_TO = 50;
|
|
||||||
|
|
||||||
function showReticleOnMouseClick() {
|
|
||||||
Reticle.visible = true;
|
|
||||||
lastMouseMoveOrClick = Date.now(); // move or click
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.mousePressEvent.connect(showReticleOnMouseClick);
|
|
||||||
Controller.mouseDoublePressEvent.connect(showReticleOnMouseClick);
|
|
||||||
|
|
||||||
Controller.mouseMoveEvent.connect(function(mouseEvent) {
|
|
||||||
var now = Date.now();
|
|
||||||
|
|
||||||
// if the reticle is hidden, and we're not in away mode...
|
|
||||||
if (!Reticle.visible && Reticle.allowMouseCapture) {
|
|
||||||
Reticle.visible = true;
|
|
||||||
if (HMD.active) {
|
|
||||||
shouldSeekToLookAt = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// even if the reticle is visible, if we're in HMD mode, and the person is moving their mouse quickly (shaking it)
|
|
||||||
// then they are probably looking for it, and we should move into seekToLookAt mode
|
|
||||||
if (HMD.active && !shouldSeekToLookAt && Reticle.allowMouseCapture) {
|
|
||||||
var dx = Reticle.position.x - lastMouseX;
|
|
||||||
var dy = Reticle.position.y - lastMouseY;
|
|
||||||
var dt = Math.max(1, (now - lastMouseMoveOrClick)); // mSecs since last mouse move
|
|
||||||
var mouseMoveDistance = Math.sqrt((dx*dx) + (dy*dy));
|
|
||||||
var mouseVelocity = mouseMoveDistance / dt;
|
|
||||||
averageMouseVelocity = (ONE_MINUS_WEIGHTING * averageMouseVelocity) + (WEIGHTING * mouseVelocity);
|
|
||||||
if (averageMouseVelocity > AVERAGE_MOUSE_VELOCITY_FOR_SEEK_TO) {
|
|
||||||
shouldSeekToLookAt = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastMouseMoveOrClick = now;
|
|
||||||
lastMouseX = mouseEvent.x;
|
|
||||||
lastMouseY = mouseEvent.y;
|
|
||||||
});
|
|
||||||
|
|
||||||
function seekToLookAt() {
|
|
||||||
// if we're currently seeking the lookAt move the mouse toward the lookat
|
|
||||||
if (shouldSeekToLookAt) {
|
|
||||||
averageMouseVelocity = 0; // reset this, these never count for movement...
|
|
||||||
var lookAt2D = HMD.getHUDLookAtPosition2D();
|
|
||||||
var currentReticlePosition = Reticle.position;
|
|
||||||
var distanceBetweenX = lookAt2D.x - Reticle.position.x;
|
|
||||||
var distanceBetweenY = lookAt2D.y - Reticle.position.y;
|
|
||||||
var moveX = distanceBetweenX / NON_LINEAR_DIVISOR;
|
|
||||||
var moveY = distanceBetweenY / NON_LINEAR_DIVISOR;
|
|
||||||
var newPosition = { x: Reticle.position.x + moveX, y: Reticle.position.y + moveY };
|
|
||||||
var closeEnoughX = false;
|
|
||||||
var closeEnoughY = false;
|
|
||||||
if (moveX < MINIMUM_SEEK_DISTANCE) {
|
|
||||||
newPosition.x = lookAt2D.x;
|
|
||||||
closeEnoughX = true;
|
|
||||||
}
|
|
||||||
if (moveY < MINIMUM_SEEK_DISTANCE) {
|
|
||||||
newPosition.y = lookAt2D.y;
|
|
||||||
closeEnoughY = true;
|
|
||||||
}
|
|
||||||
Reticle.position = newPosition;
|
|
||||||
if (closeEnoughX && closeEnoughY) {
|
|
||||||
shouldSeekToLookAt = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function autoHideReticle() {
|
|
||||||
var now = Date.now();
|
|
||||||
|
|
||||||
// sometimes we don't actually get mouse move messages (for example, if the focus has been set
|
|
||||||
// to an overlay or web page 'overlay') in but the mouse can still be moving, and we don't want
|
|
||||||
// to autohide in these cases, so we will take this opportunity to also check if the reticle
|
|
||||||
// position has changed.
|
|
||||||
if (lastMouseX != Reticle.position.x || lastMouseY != Reticle.position.y) {
|
|
||||||
lastMouseMoveOrClick = now;
|
|
||||||
lastMouseX = Reticle.position.x;
|
|
||||||
lastMouseY = Reticle.position.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we haven't moved in a long period of time, and we're not pointing at some
|
|
||||||
// system overlay (like a window), then hide the reticle
|
|
||||||
if (Reticle.visible && !Reticle.pointingAtSystemOverlay) {
|
|
||||||
var timeSinceLastMouseMove = now - lastMouseMoveOrClick;
|
|
||||||
if (timeSinceLastMouseMove > HIDE_STATIC_MOUSE_AFTER) {
|
|
||||||
Reticle.visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkReticleDepth() {
|
|
||||||
var now = Date.now();
|
|
||||||
var timeSinceLastDepthCheck = now - lastDepthCheckTime;
|
|
||||||
if (timeSinceLastDepthCheck > TIME_BETWEEN_DEPTH_CHECKS && Reticle.visible) {
|
|
||||||
var newDesiredDepth = desiredDepth;
|
|
||||||
lastDepthCheckTime = now;
|
|
||||||
var reticlePosition = Reticle.position;
|
|
||||||
|
|
||||||
// first check the 2D Overlays
|
|
||||||
if (Reticle.pointingAtSystemOverlay || Overlays.getOverlayAtPoint(reticlePosition)) {
|
|
||||||
newDesiredDepth = APPARENT_2D_OVERLAY_DEPTH;
|
|
||||||
} else {
|
|
||||||
var pickRay = Camera.computePickRay(reticlePosition.x, reticlePosition.y);
|
|
||||||
|
|
||||||
// Then check the 3D overlays
|
|
||||||
var result = Overlays.findRayIntersection(pickRay);
|
|
||||||
|
|
||||||
if (!result.intersects) {
|
|
||||||
// finally check the entities
|
|
||||||
result = Entities.findRayIntersection(pickRay, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If either the overlays or entities intersect, then set the reticle depth to
|
|
||||||
// the distance of intersection
|
|
||||||
if (result.intersects) {
|
|
||||||
newDesiredDepth = result.distance;
|
|
||||||
} else {
|
|
||||||
// if nothing intersects... set the depth to some sufficiently large depth
|
|
||||||
newDesiredDepth = APPARENT_MAXIMUM_DEPTH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the desired depth has changed, reset our fade start time
|
|
||||||
if (desiredDepth != newDesiredDepth) {
|
|
||||||
desiredDepth = newDesiredDepth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveToDesiredDepth() {
|
|
||||||
// move the reticle toward the desired depth
|
|
||||||
if (desiredDepth != Reticle.depth) {
|
|
||||||
|
|
||||||
// cut distance between desiredDepth and current depth in half until we're close enough
|
|
||||||
var distanceToAdjustThisCycle = (desiredDepth - Reticle.depth) / NON_LINEAR_DIVISOR;
|
|
||||||
if (Math.abs(distanceToAdjustThisCycle) < MINIMUM_DEPTH_ADJUST) {
|
|
||||||
newDepth = desiredDepth;
|
|
||||||
} else {
|
|
||||||
newDepth = Reticle.depth + distanceToAdjustThisCycle;
|
|
||||||
}
|
|
||||||
Reticle.setDepth(newDepth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Script.update.connect(function(deltaTime) {
|
|
||||||
autoHideReticle(); // auto hide reticle for desktop or HMD mode
|
|
||||||
if (HMD.active) {
|
|
||||||
seekToLookAt(); // handle moving the reticle toward the look at
|
|
||||||
checkReticleDepth(); // make sure reticle is at correct depth
|
|
||||||
moveToDesiredDepth(); // move the fade the reticle to the desired depth
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,477 +0,0 @@
|
||||||
//
|
|
||||||
// pistol.js
|
|
||||||
// examples
|
|
||||||
//
|
|
||||||
// Created by Eric Levin on 11/12/2015
|
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// This is an example script that turns the hydra controllers and mouse into a entity gun.
|
|
||||||
// It reads the controller, watches for trigger pulls, and adds a force to any entity it hits
|
|
||||||
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
Script.include("../../../libraries/utils.js");
|
|
||||||
Script.include("../../../libraries/constants.js");
|
|
||||||
|
|
||||||
var GUN_FORCE =20;
|
|
||||||
|
|
||||||
Messages.sendMessage('Hifi-Hand-Disabler', "both");
|
|
||||||
|
|
||||||
var gameName = "Kill All The Rats!"
|
|
||||||
// var HOST = "localhost:5000"
|
|
||||||
var HOST = "desolate-bastion-1742.herokuapp.com";
|
|
||||||
var socketClient = new WebSocket("ws://" + HOST);
|
|
||||||
var username = GlobalServices.username;
|
|
||||||
var currentScore = 0;
|
|
||||||
|
|
||||||
function score() {
|
|
||||||
currentScore++;
|
|
||||||
socketClient.send(JSON.stringify({
|
|
||||||
username: username,
|
|
||||||
score: currentScore,
|
|
||||||
gameName: gameName
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
|
||||||
var fireSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Guns/GUN-SHOT2.raw");
|
|
||||||
var LASER_LENGTH = 100;
|
|
||||||
var LASER_WIDTH = 2;
|
|
||||||
var POSE_CONTROLS = [Controller.Standard.LeftHand, Controller.Standard.RightHand];
|
|
||||||
var TRIGGER_CONTROLS = [Controller.Standard.LT, Controller.Standard.RT];
|
|
||||||
var MIN_THROWER_DELAY = 1000;
|
|
||||||
var MAX_THROWER_DELAY = 1000;
|
|
||||||
var RELOAD_INTERVAL = 5;
|
|
||||||
var GUN_MODEL = HIFI_PUBLIC_BUCKET + "cozza13/gun/m1911-handgun+1.fbx?v=4";
|
|
||||||
var BULLET_VELOCITY = 10.0;
|
|
||||||
var GUN_OFFSETS = [{
|
|
||||||
x: 0.04,
|
|
||||||
y: 0.26,
|
|
||||||
z: 0.04
|
|
||||||
}, {
|
|
||||||
x: 0.04,
|
|
||||||
y: 0.26,
|
|
||||||
z: 0.04
|
|
||||||
}];
|
|
||||||
|
|
||||||
var GUN_ORIENTATIONS = [Quat.fromPitchYawRollDegrees(0, 90, 90), Quat.fromPitchYawRollDegrees(0, -90, 270)];
|
|
||||||
|
|
||||||
//x -> y
|
|
||||||
//y -> z
|
|
||||||
// z -> x
|
|
||||||
var BARREL_OFFSETS = [ {
|
|
||||||
x: -0.12,
|
|
||||||
y: 0.12,
|
|
||||||
z: 0.04
|
|
||||||
}, {
|
|
||||||
x: 0.12,
|
|
||||||
y: 0.12,
|
|
||||||
z: 0.04
|
|
||||||
} ];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var pointers = [];
|
|
||||||
|
|
||||||
pointers.push(Overlays.addOverlay("line3d", {
|
|
||||||
start: ZERO_VECTOR,
|
|
||||||
end: ZERO_VECTOR,
|
|
||||||
color: COLORS.RED,
|
|
||||||
alpha: 1,
|
|
||||||
visible: true,
|
|
||||||
lineWidth: LASER_WIDTH
|
|
||||||
}));
|
|
||||||
|
|
||||||
pointers.push(Overlays.addOverlay("line3d", {
|
|
||||||
start: ZERO_VECTOR,
|
|
||||||
end: ZERO_VECTOR,
|
|
||||||
color: COLORS.RED,
|
|
||||||
alpha: 1,
|
|
||||||
visible: true,
|
|
||||||
lineWidth: LASER_WIDTH
|
|
||||||
}));
|
|
||||||
|
|
||||||
var mapping = Controller.newMapping();
|
|
||||||
var validPoses = [false, false];
|
|
||||||
var barrelVectors = [0, 0];
|
|
||||||
var barrelTips = [0, 0];
|
|
||||||
|
|
||||||
|
|
||||||
// If enabled, anything can be shot, otherwise, an entity needs to have "isShootable" set in its userData
|
|
||||||
var shootAnything = true;
|
|
||||||
|
|
||||||
|
|
||||||
function update(deltaTime) {
|
|
||||||
// FIXME we should also expose MyAvatar.handPoses[2], MyAvatar.tipPoses[2]
|
|
||||||
var tipPoses = [MyAvatar.leftHandTipPose, MyAvatar.rightHandTipPose];
|
|
||||||
|
|
||||||
for (var side = 0; side < 2; side++) {
|
|
||||||
// First check if the controller is valid
|
|
||||||
var controllerPose = Controller.getPoseValue(POSE_CONTROLS[side]);
|
|
||||||
validPoses[side] = controllerPose.valid;
|
|
||||||
// Need to adjust the laser
|
|
||||||
var tipPose = tipPoses[side];
|
|
||||||
var handRotation = tipPoses[side].rotation;
|
|
||||||
var barrelOffset = Vec3.multiplyQbyV(handRotation, BARREL_OFFSETS[side]);
|
|
||||||
barrelTips[side] = Vec3.sum(tipPose.translation, barrelOffset);
|
|
||||||
barrelVectors[side] = Vec3.multiplyQbyV(handRotation, {
|
|
||||||
x: 0,
|
|
||||||
y: 1,
|
|
||||||
z: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
var laserTip = Vec3.sum(Vec3.multiply(LASER_LENGTH, barrelVectors[side]), barrelTips[side]);
|
|
||||||
// Update Lasers
|
|
||||||
Overlays.editOverlay(pointers[side], {
|
|
||||||
start: barrelTips[side],
|
|
||||||
end: laserTip,
|
|
||||||
alpha: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function displayPointer(side) {
|
|
||||||
Overlays.editOverlay(pointers[side], {
|
|
||||||
visible: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function hidePointer(side) {
|
|
||||||
Overlays.editOverlay(pointers[side], {
|
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function fire(side, value) {
|
|
||||||
if (value == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Audio.playSound(fireSound, {
|
|
||||||
position: barrelTips[side],
|
|
||||||
volume: 0.5
|
|
||||||
});
|
|
||||||
|
|
||||||
var shotDirection = Vec3.normalize(barrelVectors[side]);
|
|
||||||
var pickRay = {
|
|
||||||
origin: barrelTips[side],
|
|
||||||
direction: shotDirection
|
|
||||||
};
|
|
||||||
createMuzzleFlash(barrelTips[side]);
|
|
||||||
|
|
||||||
var intersection = Entities.findRayIntersectionBlocking(pickRay, true);
|
|
||||||
if (intersection.intersects) {
|
|
||||||
Script.setTimeout(function() {
|
|
||||||
createEntityHitEffect(intersection.intersection);
|
|
||||||
if (shootAnything && intersection.properties.dynamic === 1) {
|
|
||||||
// Any dynamic entity can be shot
|
|
||||||
Entities.editEntity(intersection.entityID, {
|
|
||||||
velocity: Vec3.multiply(shotDirection, GUN_FORCE)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intersection.properties.name === "rat") {
|
|
||||||
score();
|
|
||||||
createBloodSplatter(intersection.intersection);
|
|
||||||
Entities.deleteEntity(intersection.entityID);
|
|
||||||
|
|
||||||
}
|
|
||||||
//Attempt to call entity method's shot method
|
|
||||||
var forceDirection = JSON.stringify({
|
|
||||||
forceDirection: shotDirection
|
|
||||||
});
|
|
||||||
Entities.callEntityMethod(intersection.entityID, 'onShot', [forceDirection]);
|
|
||||||
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function scriptEnding() {
|
|
||||||
Messages.sendMessage('Hifi-Hand-Disabler', 'none');
|
|
||||||
mapping.disable();
|
|
||||||
for (var i = 0; i < pointers.length; ++i) {
|
|
||||||
Overlays.deleteOverlay(pointers[i]);
|
|
||||||
}
|
|
||||||
MyAvatar.detachOne(GUN_MODEL);
|
|
||||||
MyAvatar.detachOne(GUN_MODEL);
|
|
||||||
clearPose();
|
|
||||||
}
|
|
||||||
|
|
||||||
MyAvatar.attach(GUN_MODEL, "LeftHand", GUN_OFFSETS[0], GUN_ORIENTATIONS[0], 0.40);
|
|
||||||
MyAvatar.attach(GUN_MODEL, "RightHand", GUN_OFFSETS[1], GUN_ORIENTATIONS[1], 0.40);
|
|
||||||
|
|
||||||
function showPointer(side) {
|
|
||||||
Overlays.editOverlay(pointers[side], {
|
|
||||||
visible: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mapping.from(Controller.Standard.LT).hysteresis(0.0, 0.5).to(function(value) {
|
|
||||||
fire(0, value);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
mapping.from(Controller.Standard.RT).hysteresis(0.0, 0.5).to(function(value) {
|
|
||||||
fire(1, value);
|
|
||||||
});
|
|
||||||
mapping.enable();
|
|
||||||
|
|
||||||
Script.scriptEnding.connect(scriptEnding);
|
|
||||||
Script.update.connect(update);
|
|
||||||
|
|
||||||
|
|
||||||
function createEntityHitEffect(position) {
|
|
||||||
var flash = Entities.addEntity({
|
|
||||||
type: "ParticleEffect",
|
|
||||||
position: position,
|
|
||||||
lifetime: 4,
|
|
||||||
"name": "Flash Emitter",
|
|
||||||
"color": {
|
|
||||||
red: 228,
|
|
||||||
green: 128,
|
|
||||||
blue: 12
|
|
||||||
},
|
|
||||||
"maxParticles": 1000,
|
|
||||||
"lifespan": 0.15,
|
|
||||||
"emitRate": 1000,
|
|
||||||
"emitSpeed": 1,
|
|
||||||
"speedSpread": 0,
|
|
||||||
"emitOrientation": {
|
|
||||||
"x": -0.4,
|
|
||||||
"y": 1,
|
|
||||||
"z": -0.2,
|
|
||||||
"w": 0.7071068286895752
|
|
||||||
},
|
|
||||||
"emitDimensions": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"polarStart": 0,
|
|
||||||
"polarFinish": Math.PI,
|
|
||||||
"azimuthStart": -3.1415927410125732,
|
|
||||||
"azimuthFinish": 2,
|
|
||||||
"emitAcceleration": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"accelerationSpread": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"particleRadius": 0.03,
|
|
||||||
"radiusSpread": 0.02,
|
|
||||||
"radiusStart": 0.02,
|
|
||||||
"radiusFinish": 0.03,
|
|
||||||
"colorSpread": {
|
|
||||||
red: 100,
|
|
||||||
green: 100,
|
|
||||||
blue: 20
|
|
||||||
},
|
|
||||||
"alpha": 1,
|
|
||||||
"alphaSpread": 0,
|
|
||||||
"alphaStart": 0,
|
|
||||||
"alphaFinish": 0,
|
|
||||||
"additiveBlending": true,
|
|
||||||
"textures": "http://ericrius1.github.io/PartiArt/assets/star.png"
|
|
||||||
});
|
|
||||||
|
|
||||||
Script.setTimeout(function() {
|
|
||||||
Entities.editEntity(flash, {
|
|
||||||
isEmitting: false
|
|
||||||
});
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function createBloodSplatter(position) {
|
|
||||||
var splatter = Entities.addEntity({
|
|
||||||
type: "ParticleEffect",
|
|
||||||
position: position,
|
|
||||||
lifetime: 4,
|
|
||||||
"name": "Blood Splatter",
|
|
||||||
"color": {
|
|
||||||
red: 230,
|
|
||||||
green: 2,
|
|
||||||
blue: 30
|
|
||||||
},
|
|
||||||
"maxParticles": 1000,
|
|
||||||
"lifespan": 0.3,
|
|
||||||
"emitRate": 1000,
|
|
||||||
"emitSpeed": 0.5,
|
|
||||||
"speedSpread": 0,
|
|
||||||
"emitOrientation": {
|
|
||||||
"x": -0.4,
|
|
||||||
"y": 1,
|
|
||||||
"z": -0.2,
|
|
||||||
"w": 0.7071068286895752
|
|
||||||
},
|
|
||||||
"emitDimensions": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"polarStart": 0,
|
|
||||||
"polarFinish": Math.PI,
|
|
||||||
"azimuthStart": -3.1415927410125732,
|
|
||||||
"azimuthFinish": 2,
|
|
||||||
"emitAcceleration": {
|
|
||||||
"x": 0,
|
|
||||||
"y": -5,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"accelerationSpread": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"particleRadius": 0.05,
|
|
||||||
"radiusSpread": 0.03,
|
|
||||||
"radiusStart": 0.05,
|
|
||||||
"radiusFinish": 0.05,
|
|
||||||
"colorSpread": {
|
|
||||||
red: 40,
|
|
||||||
green: 0,
|
|
||||||
blue: 30
|
|
||||||
},
|
|
||||||
"alpha": 1,
|
|
||||||
"alphaSpread": 0,
|
|
||||||
"alphaStart": 0,
|
|
||||||
"alphaFinish": 0,
|
|
||||||
"textures": "http://ericrius1.github.io/PartiArt/assets/star.png"
|
|
||||||
});
|
|
||||||
|
|
||||||
Script.setTimeout(function() {
|
|
||||||
Entities.editEntity(splatter, {
|
|
||||||
isEmitting: false
|
|
||||||
});
|
|
||||||
}, 100)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function createMuzzleFlash(position) {
|
|
||||||
var smoke = Entities.addEntity({
|
|
||||||
type: "ParticleEffect",
|
|
||||||
position: position,
|
|
||||||
lifetime: 1,
|
|
||||||
"name": "Smoke Hit Emitter",
|
|
||||||
"maxParticles": 1000,
|
|
||||||
"lifespan": 4,
|
|
||||||
"emitRate": 20,
|
|
||||||
emitSpeed: 0,
|
|
||||||
"speedSpread": 0,
|
|
||||||
"emitDimensions": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"polarStart": 0,
|
|
||||||
"polarFinish": 0,
|
|
||||||
"azimuthStart": -3.1415927410125732,
|
|
||||||
"azimuthFinish": 3.14,
|
|
||||||
"emitAcceleration": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0.5,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"accelerationSpread": {
|
|
||||||
"x": .2,
|
|
||||||
"y": 0,
|
|
||||||
"z": .2
|
|
||||||
},
|
|
||||||
"radiusSpread": .04,
|
|
||||||
"particleRadius": 0.07,
|
|
||||||
"radiusStart": 0.07,
|
|
||||||
"radiusFinish": 0.07,
|
|
||||||
"alpha": 0.7,
|
|
||||||
"alphaSpread": 0,
|
|
||||||
"alphaStart": 0,
|
|
||||||
"alphaFinish": 0,
|
|
||||||
"additiveBlending": 0,
|
|
||||||
"textures": "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"
|
|
||||||
});
|
|
||||||
Script.setTimeout(function() {
|
|
||||||
Entities.editEntity(smoke, {
|
|
||||||
isEmitting: false
|
|
||||||
});
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
var flash = Entities.addEntity({
|
|
||||||
type: "ParticleEffect",
|
|
||||||
position: position,
|
|
||||||
lifetime: 4,
|
|
||||||
"name": "Muzzle Flash",
|
|
||||||
"color": {
|
|
||||||
red: 228,
|
|
||||||
green: 128,
|
|
||||||
blue: 12
|
|
||||||
},
|
|
||||||
"maxParticles": 1000,
|
|
||||||
"lifespan": 0.1,
|
|
||||||
"emitRate": 1000,
|
|
||||||
"emitSpeed": 0.5,
|
|
||||||
"speedSpread": 0,
|
|
||||||
"emitOrientation": {
|
|
||||||
"x": -0.4,
|
|
||||||
"y": 1,
|
|
||||||
"z": -0.2,
|
|
||||||
"w": 0.7071068286895752
|
|
||||||
},
|
|
||||||
"emitDimensions": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"polarStart": 0,
|
|
||||||
"polarFinish": Math.PI,
|
|
||||||
"azimuthStart": -3.1415927410125732,
|
|
||||||
"azimuthFinish": 2,
|
|
||||||
"emitAcceleration": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"accelerationSpread": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"particleRadius": 0.05,
|
|
||||||
"radiusSpread": 0.01,
|
|
||||||
"radiusStart": 0.05,
|
|
||||||
"radiusFinish": 0.05,
|
|
||||||
"colorSpread": {
|
|
||||||
red: 100,
|
|
||||||
green: 100,
|
|
||||||
blue: 20
|
|
||||||
},
|
|
||||||
"alpha": 1,
|
|
||||||
"alphaSpread": 0,
|
|
||||||
"alphaStart": 0,
|
|
||||||
"alphaFinish": 0,
|
|
||||||
"additiveBlending": true,
|
|
||||||
"textures": "http://ericrius1.github.io/PartiArt/assets/star.png"
|
|
||||||
});
|
|
||||||
|
|
||||||
Script.setTimeout(function() {
|
|
||||||
Entities.editEntity(flash, {
|
|
||||||
isEmitting: false
|
|
||||||
});
|
|
||||||
}, 100)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
//
|
|
||||||
// Rat.js
|
|
||||||
// examples/toybox/entityScripts
|
|
||||||
//
|
|
||||||
// Created by Eric Levin on11/11/15.
|
|
||||||
// Copyright 2015 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
|
|
||||||
/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */
|
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var scriptURL = Script.resolvePath('pistol.js');
|
|
||||||
var _this;
|
|
||||||
PistolScriptSpawner = function() {
|
|
||||||
_this = this;
|
|
||||||
this.forceMultiplier = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
PistolScriptSpawner.prototype = {
|
|
||||||
|
|
||||||
enterEntity: function() {
|
|
||||||
|
|
||||||
Script.load(scriptURL);
|
|
||||||
},
|
|
||||||
|
|
||||||
preload: function(entityID) {
|
|
||||||
this.entityID = entityID;
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// entity scripts always need to return a newly constructed object of our type
|
|
||||||
return new PistolScriptSpawner();
|
|
||||||
});
|
|
|
@ -44,7 +44,7 @@ else ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
find_package(Qt5 COMPONENTS
|
find_package(Qt5 COMPONENTS
|
||||||
Gui Multimedia Network OpenGL Qml Quick Script Svg
|
Gui Multimedia Network OpenGL Qml Quick Script ScriptTools Svg
|
||||||
WebChannel WebEngine WebEngineWidgets WebKitWidgets WebSockets)
|
WebChannel WebEngine WebEngineWidgets WebKitWidgets WebSockets)
|
||||||
|
|
||||||
# grab the ui files in resources/ui
|
# grab the ui files in resources/ui
|
||||||
|
@ -201,7 +201,7 @@ include_directories("${PROJECT_SOURCE_DIR}/src")
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
${TARGET_NAME}
|
${TARGET_NAME}
|
||||||
Qt5::Gui Qt5::Network Qt5::Multimedia Qt5::OpenGL
|
Qt5::Gui Qt5::Network Qt5::Multimedia Qt5::OpenGL
|
||||||
Qt5::Qml Qt5::Quick Qt5::Script Qt5::Svg
|
Qt5::Qml Qt5::Quick Qt5::Script Qt5::ScriptTools Qt5::Svg
|
||||||
Qt5::WebChannel Qt5::WebEngine Qt5::WebEngineWidgets Qt5::WebKitWidgets
|
Qt5::WebChannel Qt5::WebEngine Qt5::WebEngineWidgets Qt5::WebKitWidgets
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ else (APPLE)
|
||||||
"${PROJECT_SOURCE_DIR}/resources"
|
"${PROJECT_SOURCE_DIR}/resources"
|
||||||
$<TARGET_FILE_DIR:${TARGET_NAME}>/resources
|
$<TARGET_FILE_DIR:${TARGET_NAME}>/resources
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||||
"${CMAKE_SOURCE_DIR}/examples"
|
"${CMAKE_SOURCE_DIR}/scripts"
|
||||||
$<TARGET_FILE_DIR:${TARGET_NAME}>/scripts
|
$<TARGET_FILE_DIR:${TARGET_NAME}>/scripts
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ endif (APPLE)
|
||||||
if (SCRIPTS_INSTALL_DIR)
|
if (SCRIPTS_INSTALL_DIR)
|
||||||
# setup install of scripts beside interface executable
|
# setup install of scripts beside interface executable
|
||||||
install(
|
install(
|
||||||
DIRECTORY "${CMAKE_SOURCE_DIR}/examples/"
|
DIRECTORY "${CMAKE_SOURCE_DIR}/scripts/"
|
||||||
DESTINATION ${SCRIPTS_INSTALL_DIR}/scripts
|
DESTINATION ${SCRIPTS_INSTALL_DIR}/scripts
|
||||||
COMPONENT ${CLIENT_COMPONENT}
|
COMPONENT ${CLIENT_COMPONENT}
|
||||||
)
|
)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -274,7 +274,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "walkFwd",
|
"id": "walkFwd",
|
||||||
"interpTarget": 15,
|
"interpTarget": 16,
|
||||||
"interpDuration": 6,
|
"interpDuration": 6,
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isNotMoving", "state": "idle" },
|
{ "var": "isNotMoving", "state": "idle" },
|
||||||
|
@ -497,7 +497,7 @@
|
||||||
"data": {
|
"data": {
|
||||||
"url": "animations/idle.fbx",
|
"url": "animations/idle.fbx",
|
||||||
"startFrame": 0.0,
|
"startFrame": 0.0,
|
||||||
"endFrame": 90.0,
|
"endFrame": 300.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": true
|
"loopFlag": true
|
||||||
},
|
},
|
||||||
|
@ -509,7 +509,7 @@
|
||||||
"data": {
|
"data": {
|
||||||
"url": "animations/talk.fbx",
|
"url": "animations/talk.fbx",
|
||||||
"startFrame": 0.0,
|
"startFrame": 0.0,
|
||||||
"endFrame": 801.0,
|
"endFrame": 800.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": true
|
"loopFlag": true
|
||||||
},
|
},
|
||||||
|
@ -572,7 +572,7 @@
|
||||||
"data": {
|
"data": {
|
||||||
"url": "animations/idle_to_walk.fbx",
|
"url": "animations/idle_to_walk.fbx",
|
||||||
"startFrame": 1.0,
|
"startFrame": 1.0,
|
||||||
"endFrame": 19.0,
|
"endFrame": 13.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": false
|
"loopFlag": false
|
||||||
},
|
},
|
||||||
|
@ -631,11 +631,12 @@
|
||||||
"id": "turnRight",
|
"id": "turnRight",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "animations/turn_right.fbx",
|
"url": "animations/turn_left.fbx",
|
||||||
"startFrame": 0.0,
|
"startFrame": 0.0,
|
||||||
"endFrame": 30.0,
|
"endFrame": 30.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": true
|
"loopFlag": true,
|
||||||
|
"mirrorFlag": true
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
{
|
{
|
||||||
"name": "Vive to Standard",
|
"name": "Vive to Standard",
|
||||||
"channels": [
|
"channels": [
|
||||||
{ "from": "Vive.LY", "when": "Vive.LS", "filters": "invert", "to": "Standard.LY" },
|
{ "from": "Vive.LY", "when": "Vive.LS", "filters": ["invert" ,{ "type": "deadZone", "min": 0.6 }], "to": "Standard.LY" },
|
||||||
{ "from": "Vive.LX", "when": "Vive.LS", "to": "Standard.LX" },
|
{ "from": "Vive.LX", "when": "Vive.LS", "filters": [{ "type": "deadZone", "min": 0.6 }], "to": "Standard.LX" },
|
||||||
|
|
||||||
{ "from": "Vive.LT", "to": "Standard.LT" },
|
{ "from": "Vive.LT", "to": "Standard.LT" },
|
||||||
{ "from": "Vive.LB", "to": "Standard.LB" },
|
{ "from": "Vive.LeftGrip", "to": "Standard.LB" },
|
||||||
{ "from": "Vive.LS", "to": "Standard.LS" },
|
{ "from": "Vive.LS", "to": "Standard.LS" },
|
||||||
|
{ "from": "Vive.LSTouch", "to": "Standard.LSTouch" },
|
||||||
|
|
||||||
{ "from": "Vive.RY", "when": "Vive.RS", "filters": "invert", "to": "Standard.RY" },
|
{ "from": "Vive.RY", "when": "Vive.RS", "filters": ["invert", { "type": "deadZone", "min": 0.6 }], "to": "Standard.RY" },
|
||||||
{ "from": "Vive.RX", "when": "Vive.RS", "to": "Standard.RX" },
|
{ "from": "Vive.RX", "when": "Vive.RS", "filters": [{ "type": "deadZone", "min": 0.6 }], "to": "Standard.RX" },
|
||||||
|
|
||||||
{ "from": "Vive.RT", "to": "Standard.RT" },
|
{ "from": "Vive.RT", "to": "Standard.RT" },
|
||||||
{ "from": "Vive.RB", "to": "Standard.RB" },
|
{ "from": "Vive.RightGrip", "to": "Standard.RB" },
|
||||||
{ "from": "Vive.RS", "to": "Standard.RS" },
|
{ "from": "Vive.RS", "to": "Standard.RS" },
|
||||||
|
{ "from": "Vive.RSTouch", "to": "Standard.RSTouch" },
|
||||||
|
|
||||||
{ "from": "Vive.LeftApplicationMenu", "to": "Standard.Back" },
|
{ "from": "Vive.LeftApplicationMenu", "to": "Standard.Back" },
|
||||||
{ "from": "Vive.RightApplicationMenu", "to": "Standard.Start" },
|
{ "from": "Vive.RightApplicationMenu", "to": "Standard.Start" },
|
||||||
|
|
|
@ -1,31 +1,52 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
x="0px" y="0px" width="1600px" height="100px" viewBox="0 0 1600 100" xml:space="preserve">
|
viewBox="0 0 1600 100" style="enable-background:new 0 0 1600 100;" xml:space="preserve">
|
||||||
<path fill="#FFFFFF" d="M92.8,69.3c-0.8-1.5-1.9-2.7-3.1-3.8c4.4-11.4,3.7-24.6-2.6-35.8c-9.2-16.3-28.3-24.4-46.3-20l-3.1,0.7
|
<style type="text/css">
|
||||||
l4.9,8.7l1.7-0.3c13.7-2.7,27.6,3.6,34.5,15.7c4.9,8.7,5.5,18.9,1.9,27.9c-2.1,0.1-4.3,0.6-6.2,1.8c-6.5,3.7-8.8,12-5.1,18.5
|
.st0{fill:#FFFFFF;}
|
||||||
c3.7,6.5,12,8.8,18.5,5.1C94.2,84.1,96.5,75.8,92.8,69.3z"/>
|
</style>
|
||||||
<path fill="#FFFFFF" d="M54.2,82.6l-1.5,0.1c-12.3,0.8-24.2-5.6-30.2-16.3c-3.8-6.6-4.9-14.2-3.7-21.3c2.8,0.4,5.9-0.1,8.6-1.6
|
<path class="st0" d="M92.8,69.3c-0.8-1.5-1.9-2.7-3.1-3.8c4.4-11.4,3.7-24.6-2.6-35.8c-9.2-16.3-28.3-24.4-46.3-20l-3.1,0.7l4.9,8.7
|
||||||
c6.5-3.7,8.8-12,5.1-18.5s-12-8.8-18.5-5.1C7.7,23.7,5.4,32,9,38.5c0.3,0.6,0.7,1.2,1.2,1.7c-2.6,10.3-1.4,21.5,4.1,31.1
|
l1.7-0.3c13.7-2.7,27.6,3.6,34.5,15.7c4.9,8.7,5.5,18.9,1.9,27.9c-2.1,0.1-4.3,0.6-6.2,1.8c-6.5,3.7-8.8,12-5.1,18.5
|
||||||
c7.5,13.2,21.5,21.2,36.5,21.2c1.8,0,3.5-0.1,5.2-0.3l3.6-0.4L54.2,82.6z"/>
|
c3.7,6.5,12,8.8,18.5,5.1C94.2,84.1,96.5,75.8,92.8,69.3z"/>
|
||||||
<path fill="#FFFFFF" d="M67.2,63.4H33.8c-1,0-2.1-0.5-2.6-1.5c-0.5-0.9-0.5-2.1,0-3L47.8,30c0.5-0.9,1.6-1.5,2.6-1.5
|
<path class="st0" d="M54.2,82.6l-1.5,0.1c-12.3,0.8-24.2-5.6-30.2-16.3c-3.8-6.6-4.9-14.2-3.7-21.3c2.8,0.4,5.9-0.1,8.6-1.6
|
||||||
s2.1,0.5,2.6,1.5l16.7,28.9c0.5,0.9,0.5,2.1,0,3C69.3,62.9,68.3,63.4,67.2,63.4z M39,57.4h23L50.4,37.5L39,57.4z"/>
|
c6.5-3.7,8.8-12,5.1-18.5s-12-8.8-18.5-5.1C7.7,23.7,5.4,32,9,38.5c0.3,0.6,0.7,1.2,1.2,1.7c-2.6,10.3-1.4,21.5,4.1,31.1
|
||||||
<polygon fill="#FFFFFF" points="175.4,30.6 149.9,8 123.9,30.7 139,30.7 139.2,59.6 161,59.3 160.8,30.7 "/>
|
c7.5,13.2,21.5,21.2,36.5,21.2c1.8,0,3.5-0.1,5.2-0.3l3.6-0.4L54.2,82.6z"/>
|
||||||
<polygon fill="#FFFFFF" points="225.6,39.8 251.1,62.5 277.1,39.8 261.9,39.8 261.7,8.9 240,9.2 240.2,39.8 "/>
|
<path class="st0" d="M67.2,63.4H33.8c-1,0-2.1-0.5-2.6-1.5c-0.5-0.9-0.5-2.1,0-3L47.8,30c0.5-0.9,1.6-1.5,2.6-1.5S52.5,29,53,30
|
||||||
<path fill="#FFFFFF" d="M174.3,42.8c1.8,3.7,2.8,7.8,2.8,12.1c0,15.2-12.3,27.5-27.5,27.5c-15.2,0-27.5-12.3-27.5-27.5
|
l16.7,28.9c0.5,0.9,0.5,2.1,0,3C69.3,62.9,68.3,63.4,67.2,63.4z M39,57.4h23L50.4,37.5L39,57.4z"/>
|
||||||
c0-4.4,1-8.5,2.9-12.1h-7.9c-1.4,3.8-2.2,7.8-2.2,12.1c0,19.2,15.6,34.7,34.7,34.7c19.2,0,34.7-15.6,34.7-34.7
|
<polygon class="st0" points="175.4,30.6 149.9,8 123.9,30.7 139,30.7 139.2,59.6 161,59.3 160.8,30.7 "/>
|
||||||
c0-4.3-0.8-8.3-2.2-12.1H174.3z"/>
|
<polygon class="st0" points="225.6,39.8 251.1,62.5 277.1,39.8 261.9,39.8 261.7,8.9 240,9.2 240.2,39.8 "/>
|
||||||
<path fill="#FFFFFF" d="M278.8,53c0.1,0.7,0.1,1.5,0.1,2.2c0,15.2-12.4,27.6-27.6,27.6c-15.2,0-27.6-12.4-27.6-27.6
|
<path class="st0" d="M174.3,42.8c1.8,3.7,2.8,7.8,2.8,12.1c0,15.2-12.3,27.5-27.5,27.5s-27.5-12.3-27.5-27.5c0-4.4,1-8.5,2.9-12.1
|
||||||
c0-1.1,0.1-2.1,0.2-3.1c-2.1-2.1-4.1-4.1-6.2-6.2c-0.8,3-1.3,6.1-1.3,9.3c0,19.2,15.6,34.9,34.9,34.9s34.9-15.6,34.9-34.9
|
h-7.9c-1.4,3.8-2.2,7.8-2.2,12.1c0,19.2,15.6,34.7,34.7,34.7c19.2,0,34.7-15.6,34.7-34.7c0-4.3-0.8-8.3-2.2-12.1
|
||||||
c0-2.9-0.4-5.8-1.1-8.5L278.8,53z"/>
|
C182.1,42.8,174.3,42.8,174.3,42.8z"/>
|
||||||
<circle fill="none" stroke="#000000" stroke-width="7" stroke-miterlimit="10" stroke-dasharray="7.7202,7.7202" cx="-174" cy="-5.8" r="14.7"/>
|
<path class="st0" d="M278.8,53c0.1,0.7,0.1,1.5,0.1,2.2c0,15.2-12.4,27.6-27.6,27.6c-15.2,0-27.6-12.4-27.6-27.6
|
||||||
<path d="M-174-10.6c2.6,0,4.7,2.1,4.7,4.7s-2.1,4.7-4.7,4.7s-4.7-2.1-4.7-4.7S-176.6-10.6-174-10.6 M-174-17.6
|
c0-1.1,0.1-2.1,0.2-3.1c-2.1-2.1-4.1-4.1-6.2-6.2c-0.8,3-1.3,6.1-1.3,9.3c0,19.2,15.6,34.9,34.9,34.9s34.9-15.6,34.9-34.9
|
||||||
c-6.5,0-11.7,5.3-11.7,11.7s5.3,11.7,11.7,11.7s11.7-5.3,11.7-11.7S-167.5-17.6-174-17.6L-174-17.6z"/>
|
c0-2.9-0.4-5.8-1.1-8.5L278.8,53z"/>
|
||||||
<path fill="#FFFFFF" d="M353.3,91.2c-0.3,0-0.7,0-1,0c-1.8-0.2-3.5-0.4-5.3-0.7c-21.3-3.6-35.2-22.8-32-44.2
|
<path class="st0" d="M353.3,91.2c-0.3,0-0.7,0-1,0c-1.8-0.2-3.5-0.4-5.3-0.7c-21.3-3.6-35.2-22.8-32-44.2
|
||||||
c2.7-18.2,17.7-31.4,36.8-32.5c17.2-0.9,33.8,11.4,38.2,28.5c0.8,3.1,1.1,6.3,1.6,9.5c0,0.3,0,0.7,0,1c-0.2,0.9-0.4,1.8-0.5,2.7
|
c2.7-18.2,17.7-31.4,36.8-32.5c17.2-0.9,33.8,11.4,38.2,28.5c0.8,3.1,1.1,6.3,1.6,9.5c0,0.3,0,0.7,0,1c-0.2,0.9-0.4,1.8-0.5,2.7
|
||||||
c-1.3,16.3-12.9,30.1-28.8,34C359.3,90.4,356.3,90.7,353.3,91.2z M353.7,83.9c8.3,0,16.1-3.4,22.6-9.9c2.2-2.2,2-3.1-0.7-4.5
|
c-1.3,16.3-12.9,30.1-28.8,34C359.3,90.4,356.3,90.7,353.3,91.2z M353.7,83.9c8.3,0,16.1-3.4,22.6-9.9c2.2-2.2,2-3.1-0.7-4.5
|
||||||
c-3.9-1.9-7.8-3.7-11.7-5.6c-4-2-4.6-8.1-1.1-10.8c2-1.5,2.4-3.7,2.1-5.9c-0.2-1.8-1-3.5-1.2-5.3c-0.6-6-5.2-10.2-11.1-10.1
|
c-3.9-1.9-7.8-3.7-11.7-5.6c-4-2-4.6-8.1-1.1-10.8c2-1.5,2.4-3.7,2.1-5.9c-0.2-1.8-1-3.5-1.2-5.3c-0.6-6-5.2-10.2-11.1-10.1
|
||||||
c-5.9,0.1-10.4,4.8-10.6,10.9c-0.1,1.4-0.4,2.8-0.9,4.1c-0.6,1.9,0.1,4.9,1.7,6.3c3.8,3.1,3.1,9-1.4,11.2c-3.6,1.7-7.2,3.4-10.8,5.2
|
s-10.4,4.8-10.6,10.9c-0.1,1.4-0.4,2.8-0.9,4.1c-0.6,1.9,0.1,4.9,1.7,6.3c3.8,3.1,3.1,9-1.4,11.2c-3.6,1.7-7.2,3.4-10.8,5.2
|
||||||
c-3.4,1.6-3.6,2.5-0.8,5.1C336.2,80.6,343.8,83.9,353.7,83.9z"/>
|
c-3.4,1.6-3.6,2.5-0.8,5.1C336.2,80.6,343.8,83.9,353.7,83.9z"/>
|
||||||
<polygon fill="#FFFFFF" points="445.3,14.1 484.6,14.1 461.5,38.2 485.6,41.4 422.2,86.9 441.2,53.4 425.6,49.3 "/>
|
<polygon class="st0" points="445.3,14.1 484.6,14.1 461.5,38.2 485.6,41.4 422.2,86.9 441.2,53.4 425.6,49.3 "/>
|
||||||
</svg>
|
<path class="st0" d="M564.7,53.2l0.1-8.7l-22.9-0.2c0.1-0.5,0.2-1.1,0.2-1.6c0.2-6.1,4.7-10.8,10.6-10.9c5.9-0.1,10.5,4.1,11.1,10.1
|
||||||
|
c0.1,0.9,0.3,1.7,0.6,2.6l26.7,0.2c-3.3-17.9-19-31.4-37.9-31.4c-18.6,0-34.2,13.2-37.8,30.8l26.4,0.2l0,0l-0.9,0l-0.1,8.7
|
||||||
|
l-26.2-0.2c0.5,20.8,17.5,37.6,38.5,37.6c20.7,0,37.6-16.4,38.5-36.9L564.7,53.2z M576.3,74c-6.5,6.5-14.3,9.9-22.6,9.9
|
||||||
|
c-9.9,0-17.5-3.3-23.9-9.3c-2.8-2.6-2.6-3.5,0.8-5.1c3.6-1.8,7.2-3.5,10.8-5.2c4.5-2.2,5.2-8.1,1.4-11.2c0,0-0.1-0.1-0.1-0.1l20,0.2
|
||||||
|
c-3.4,2.7-2.8,8.7,1.2,10.7c3.9,1.9,7.8,3.7,11.7,5.6C578.3,70.9,578.5,71.8,576.3,74z"/>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M638.5,48.2c-1.2-1-2.3-2.2-3.2-3.5h-16.7v9.2h29.1c-1.4-0.6-2.6-1.3-4-2.2C641.6,50.4,640.3,49.7,638.5,48.2z
|
||||||
|
"/>
|
||||||
|
<path class="st0" d="M684.9,44.7h-31.3c1,0.5,2.1,1,3.2,1.5c2.2,1,3.5,1.8,5.6,3.1c2.1,1.3,4.2,2.3,6,3.8c0.4,0.3,0.7,0.6,1,0.9
|
||||||
|
h15.5V44.7z"/>
|
||||||
|
<path class="st0" d="M651.5,44.2c-1.4-0.7-2.6-1.4-3.6-2.2c-1.1-0.8-1.9-1.7-2.5-2.8c-0.6-1-0.9-2.2-0.9-3.7c0-2.1,0.7-3.8,2-5.1
|
||||||
|
c1.3-1.3,3.2-2,5.7-2c1.1,0,2.2,0.1,3.2,0.4c1,0.3,1.9,0.8,2.7,1.4c0.8,0.7,1.5,1.6,2,2.7c0.5,1.1,0.9,2.5,1.1,4.2h7.4
|
||||||
|
c0.2,0,0.5,0,0.9,0c0.4,0,0.9,0,1.3,0c0.5,0,0.9,0,1.3,0c0.4,0,0.7,0,0.9,0c-0.1-3.3-0.7-6.1-1.8-8.5s-2.5-4.4-4.4-5.9
|
||||||
|
c-1.9-1.5-4-2.7-6.5-3.4c-2.5-0.7-5.1-1.1-8-1.1c-2.6,0-5,0.4-7.4,1.1c-2.4,0.7-4.4,1.8-6.3,3.2c-1.8,1.4-3.3,3.2-4.3,5.3
|
||||||
|
c-1.1,2.1-1.6,4.6-1.6,7.6c0,3,0.6,5.5,1.7,7.5c0.3,0.6,0.7,1.2,1.1,1.8h17.3C652.2,44.5,651.9,44.3,651.5,44.2z"/>
|
||||||
|
<path class="st0" d="M651.1,55c1.5,0.7,2.9,1.3,4.2,1.9s2.6,1.3,3.6,2.1c1,0.8,1.9,1.7,2.5,2.8s0.9,2.4,0.9,4c0,1.7-0.3,3.2-1,4.3
|
||||||
|
c-0.7,1.1-1.5,2-2.5,2.7c-1,0.7-2.1,1.1-3.3,1.4c-1.2,0.3-2.4,0.4-3.5,0.4c-1.3,0-2.5-0.2-3.7-0.7c-1.1-0.4-2.1-1.2-2.9-2.1
|
||||||
|
c-0.8-1-1.5-2.3-2-3.8c-0.5-1.6-0.8-3.5-0.8-5.7h-12.1c0.1,3.7,0.8,7,1.9,9.8c1.2,2.8,2.7,5.2,4.7,7c1.9,1.9,4.2,3.3,6.7,4.2
|
||||||
|
s5.3,1.4,8.1,1.4c2.9,0,5.8-0.4,8.4-1.1c2.7-0.7,5-1.9,7.1-3.5c2-1.6,3.7-3.6,4.9-6.1s1.8-5.5,1.8-9.1c0-2.6-0.5-4.9-1.6-6.8
|
||||||
|
c-0.9-1.5-2-2.9-3.3-4.1h-20.7C649.5,54.3,650.3,54.6,651.1,55z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 4.7 KiB |
|
@ -15,7 +15,7 @@
|
||||||
viewBox="0 0 1440 200"
|
viewBox="0 0 1440 200"
|
||||||
id="svg4136"
|
id="svg4136"
|
||||||
inkscape:version="0.91 r13725"
|
inkscape:version="0.91 r13725"
|
||||||
sodipodi:docname="address-bar.002.svg">
|
sodipodi:docname="address-bar.svg">
|
||||||
<metadata
|
<metadata
|
||||||
id="metadata4144">
|
id="metadata4144">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
|
@ -39,16 +39,16 @@
|
||||||
guidetolerance="10"
|
guidetolerance="10"
|
||||||
inkscape:pageopacity="0"
|
inkscape:pageopacity="0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:window-width="1835"
|
inkscape:window-width="1536"
|
||||||
inkscape:window-height="1057"
|
inkscape:window-height="687"
|
||||||
id="namedview4140"
|
id="namedview4140"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:zoom="0.61319416"
|
inkscape:zoom="0.61319416"
|
||||||
inkscape:cx="132.58366"
|
inkscape:cx="670.06567"
|
||||||
inkscape:cy="52.468468"
|
inkscape:cy="52.468468"
|
||||||
inkscape:window-x="77"
|
inkscape:window-x="105"
|
||||||
inkscape:window-y="-8"
|
inkscape:window-y="0"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="0"
|
||||||
inkscape:current-layer="svg4136" />
|
inkscape:current-layer="svg4136" />
|
||||||
<rect
|
<rect
|
||||||
style="fill:#ededed;fill-opacity:1;stroke:none;stroke-linejoin:round;stroke-opacity:1"
|
style="fill:#ededed;fill-opacity:1;stroke:none;stroke-linejoin:round;stroke-opacity:1"
|
||||||
|
@ -60,14 +60,14 @@
|
||||||
rx="16.025024"
|
rx="16.025024"
|
||||||
ry="17.019567" />
|
ry="17.019567" />
|
||||||
<rect
|
<rect
|
||||||
style="fill:#dadada;fill-opacity:1;stroke:#cbcbcb;stroke-width:0.33821851;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
style="fill:#dadada;fill-opacity:1;stroke:#cbcbcb;stroke-width:0.35830048;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||||
id="rect4135"
|
id="rect4135"
|
||||||
width="292.86267"
|
width="328.72031"
|
||||||
height="139.66179"
|
height="139.64169"
|
||||||
x="150.32542"
|
x="150.33546"
|
||||||
y="30.169102"
|
y="30.179144"
|
||||||
rx="16.817432"
|
rx="18.876532"
|
||||||
ry="20.612938" />
|
ry="20.609974" />
|
||||||
<circle
|
<circle
|
||||||
style="fill:#b8b8b8;fill-opacity:1;stroke:none;stroke-opacity:1"
|
style="fill:#b8b8b8;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||||
id="path4146"
|
id="path4146"
|
||||||
|
@ -78,11 +78,4 @@
|
||||||
d="m 100,36.000005 c -22.1,0 -40,17.9 -40,39.999995 0,30 40,88 40,88 0,0 40,-58 40,-88 0,-22.099995 -17.9,-39.999995 -40,-39.999995 z m 0,22 c 9.9,0 18,8.099995 18,17.999995 0,9.9 -8.1,18 -18,18 -9.9,0 -18,-8.1 -18,-18 0,-9.9 8.1,-17.999995 18,-17.999995 z"
|
d="m 100,36.000005 c -22.1,0 -40,17.9 -40,39.999995 0,30 40,88 40,88 0,0 40,-58 40,-88 0,-22.099995 -17.9,-39.999995 -40,-39.999995 z m 0,22 c 9.9,0 18,8.099995 18,17.999995 0,9.9 -8.1,18 -18,18 -9.9,0 -18,-8.1 -18,-18 0,-9.9 8.1,-17.999995 18,-17.999995 z"
|
||||||
id="path4138"
|
id="path4138"
|
||||||
inkscape:connector-curvature="0" />
|
inkscape:connector-curvature="0" />
|
||||||
<rect
|
|
||||||
style="fill:#bdbdbd;fill-opacity:1;stroke:none;stroke-width:0.30000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
id="rect4136"
|
|
||||||
width="4"
|
|
||||||
height="100"
|
|
||||||
x="310.12924"
|
|
||||||
y="50" />
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.5 KiB |
48
interface/resources/images/home-button.svg
Normal file
48
interface/resources/images/home-button.svg
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="Layer_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 320 280"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
sodipodi:docname="home-button.svg"
|
||||||
|
width="320"
|
||||||
|
height="280"><metadata
|
||||||
|
id="metadata4143"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs4141" /><sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1827"
|
||||||
|
inkscape:window-height="1057"
|
||||||
|
id="namedview4139"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.2263883"
|
||||||
|
inkscape:cx="135.72814"
|
||||||
|
inkscape:cy="175.61874"
|
||||||
|
inkscape:window-x="85"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Layer_1" /><polyline
|
||||||
|
points="261,116.2 420.4,261.1 361.7,261.1 361.7,394.5 160.4,394.5 160.4,261.1 101.8,261.1 261,116.2 "
|
||||||
|
id="polyline4137"
|
||||||
|
transform="translate(-101.1,-115.35)"
|
||||||
|
style="fill:#535353;fill-opacity:1" /></svg>
|
After Width: | Height: | Size: 1.7 KiB |
|
@ -55,15 +55,35 @@ Window {
|
||||||
property int inputAreaHeight: 56.0 * root.scale // Height of the background's input area
|
property int inputAreaHeight: 56.0 * root.scale // Height of the background's input area
|
||||||
property int inputAreaStep: (height - inputAreaHeight) / 2
|
property int inputAreaStep: (height - inputAreaHeight) / 2
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: homeButton
|
||||||
|
source: "../images/home-button.svg"
|
||||||
|
width: 29
|
||||||
|
height: 26
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: parent.height + 2 * hifi.layout.spacing
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
onClicked: {
|
||||||
|
addressBarDialog.loadHome()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: backArrow
|
id: backArrow
|
||||||
source: addressBarDialog.backEnabled ? "../images/left-arrow.svg" : "../images/left-arrow-disabled.svg"
|
source: addressBarDialog.backEnabled ? "../images/left-arrow.svg" : "../images/left-arrow-disabled.svg"
|
||||||
|
width: 22
|
||||||
|
height: 26
|
||||||
anchors {
|
anchors {
|
||||||
fill: parent
|
left: homeButton.right
|
||||||
leftMargin: parent.height + hifi.layout.spacing + 6
|
leftMargin: 2 * hifi.layout.spacing
|
||||||
rightMargin: parent.height + hifi.layout.spacing * 60
|
verticalCenter: parent.verticalCenter
|
||||||
topMargin: parent.inputAreaStep + parent.inputAreaStep + hifi.layout.spacing
|
|
||||||
bottomMargin: parent.inputAreaStep + parent.inputAreaStep + hifi.layout.spacing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
@ -78,12 +98,12 @@ Window {
|
||||||
Image {
|
Image {
|
||||||
id: forwardArrow
|
id: forwardArrow
|
||||||
source: addressBarDialog.forwardEnabled ? "../images/right-arrow.svg" : "../images/right-arrow-disabled.svg"
|
source: addressBarDialog.forwardEnabled ? "../images/right-arrow.svg" : "../images/right-arrow-disabled.svg"
|
||||||
|
width: 22
|
||||||
|
height: 26
|
||||||
anchors {
|
anchors {
|
||||||
fill: parent
|
left: backArrow.right
|
||||||
leftMargin: parent.height + hifi.layout.spacing * 9
|
leftMargin: 2 * hifi.layout.spacing
|
||||||
rightMargin: parent.height + hifi.layout.spacing * 53
|
verticalCenter: parent.verticalCenter
|
||||||
topMargin: parent.inputAreaStep + parent.inputAreaStep + hifi.layout.spacing
|
|
||||||
bottomMargin: parent.inputAreaStep + parent.inputAreaStep + hifi.layout.spacing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
@ -101,7 +121,7 @@ Window {
|
||||||
focus: true
|
focus: true
|
||||||
anchors {
|
anchors {
|
||||||
fill: parent
|
fill: parent
|
||||||
leftMargin: parent.height + parent.height + hifi.layout.spacing * 5
|
leftMargin: parent.height + parent.height + hifi.layout.spacing * 7
|
||||||
rightMargin: hifi.layout.spacing * 2
|
rightMargin: hifi.layout.spacing * 2
|
||||||
topMargin: parent.inputAreaStep + hifi.layout.spacing
|
topMargin: parent.inputAreaStep + hifi.layout.spacing
|
||||||
bottomMargin: parent.inputAreaStep + hifi.layout.spacing
|
bottomMargin: parent.inputAreaStep + hifi.layout.spacing
|
||||||
|
|
|
@ -24,7 +24,6 @@ Window {
|
||||||
title: "Asset Browser"
|
title: "Asset Browser"
|
||||||
resizable: true
|
resizable: true
|
||||||
destroyOnInvisible: true
|
destroyOnInvisible: true
|
||||||
x: 40; y: 40
|
|
||||||
implicitWidth: 384; implicitHeight: 640
|
implicitWidth: 384; implicitHeight: 640
|
||||||
minSize: Qt.vector2d(200, 300)
|
minSize: Qt.vector2d(200, 300)
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ Hifi.AvatarInputs {
|
||||||
readonly property int iconPadding: 5
|
readonly property int iconPadding: 5
|
||||||
|
|
||||||
readonly property bool shouldReposition: true
|
readonly property bool shouldReposition: true
|
||||||
|
|
||||||
Settings {
|
Settings {
|
||||||
category: "Overlay.AvatarInputs"
|
category: "Overlay.AvatarInputs"
|
||||||
property alias x: root.x
|
property alias x: root.x
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
|
//
|
||||||
|
// InfoView.qml
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 27 Apr 2015
|
||||||
|
// Copyright 2015 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
|
||||||
|
//
|
||||||
|
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
import Hifi 1.0 as Hifi
|
import Hifi 1.0 as Hifi
|
||||||
|
|
||||||
import "controls"
|
import "controls-uit"
|
||||||
import "windows" as Windows
|
import "windows-uit" as Windows
|
||||||
|
|
||||||
Windows.Window {
|
Windows.Window {
|
||||||
id: root
|
id: root
|
||||||
|
@ -12,14 +22,29 @@ Windows.Window {
|
||||||
|
|
||||||
Hifi.InfoView {
|
Hifi.InfoView {
|
||||||
id: infoView
|
id: infoView
|
||||||
// Fill the client area
|
width: pane.contentWidth
|
||||||
anchors.fill: parent
|
implicitHeight: pane.scrollHeight
|
||||||
|
|
||||||
WebView {
|
WebView {
|
||||||
id: webview
|
id: webview
|
||||||
objectName: "WebView"
|
objectName: "WebView"
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
url: infoView.url
|
url: infoView.url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
centerWindow(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
|
centerWindow(root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function centerWindow() {
|
||||||
|
desktop.centerOnVisible(root);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,21 @@
|
||||||
import QtQuick 2.3
|
//
|
||||||
import QtQuick.Controls 1.2
|
// QmlWebWindow.qml
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 17 Dec 2015
|
||||||
|
// Copyright 2015 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
|
||||||
|
//
|
||||||
|
|
||||||
|
import QtQuick 2.5
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
import QtWebEngine 1.1
|
import QtWebEngine 1.1
|
||||||
import QtWebChannel 1.0
|
import QtWebChannel 1.0
|
||||||
|
|
||||||
import "windows" as Windows
|
import "windows-uit" as Windows
|
||||||
import "controls" as Controls
|
import "controls-uit" as Controls
|
||||||
import "styles"
|
import "styles-uit"
|
||||||
|
|
||||||
Windows.Window {
|
Windows.Window {
|
||||||
id: root
|
id: root
|
||||||
|
@ -29,11 +39,16 @@ Windows.Window {
|
||||||
// missing signal
|
// missing signal
|
||||||
signal sendToScript(var message);
|
signal sendToScript(var message);
|
||||||
|
|
||||||
Controls.WebView {
|
Item {
|
||||||
id: webview
|
width: pane.contentWidth
|
||||||
url: "about:blank"
|
implicitHeight: pane.scrollHeight
|
||||||
anchors.fill: parent
|
|
||||||
focus: true
|
Controls.WebView {
|
||||||
webChannel.registeredObjects: [eventBridgeWrapper]
|
id: webview
|
||||||
|
url: "about:blank"
|
||||||
|
anchors.fill: parent
|
||||||
|
focus: true
|
||||||
|
webChannel.registeredObjects: [eventBridgeWrapper]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // dialog
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ WebEngineView {
|
||||||
id: root
|
id: root
|
||||||
property var newUrl;
|
property var newUrl;
|
||||||
|
|
||||||
|
profile.httpUserAgent: "Mozilla/5.0 Chrome (HighFidelityInterface)"
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
console.log("Connecting JS messaging to Hifi Logging")
|
console.log("Connecting JS messaging to Hifi Logging")
|
||||||
// Ensure the JS from the web-engine makes it to our logging
|
// Ensure the JS from the web-engine makes it to our logging
|
||||||
|
|
|
@ -21,7 +21,9 @@ FocusScope {
|
||||||
objectName: "desktop"
|
objectName: "desktop"
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
property rect recommendedRect: rect(0,0,0,0);
|
readonly property int invalid_position: -9999;
|
||||||
|
property rect recommendedRect: Qt.rect(0,0,0,0);
|
||||||
|
property var expectedChildren;
|
||||||
|
|
||||||
onHeightChanged: d.handleSizeChanged();
|
onHeightChanged: d.handleSizeChanged();
|
||||||
|
|
||||||
|
@ -55,13 +57,18 @@ FocusScope {
|
||||||
|
|
||||||
function handleSizeChanged() {
|
function handleSizeChanged() {
|
||||||
var oldRecommendedRect = recommendedRect;
|
var oldRecommendedRect = recommendedRect;
|
||||||
var newRecommendedRectJS = Controller.getRecommendedOverlayRect();
|
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect();
|
||||||
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
||||||
newRecommendedRectJS.width,
|
newRecommendedRectJS.width,
|
||||||
newRecommendedRectJS.height);
|
newRecommendedRectJS.height);
|
||||||
|
|
||||||
if (oldRecommendedRect != Qt.rect(0,0,0,0)
|
var oldChildren = expectedChildren;
|
||||||
&& oldRecommendedRect != newRecommendedRect) {
|
var newChildren = d.getRepositionChildren();
|
||||||
|
if (oldRecommendedRect != Qt.rect(0,0,0,0)
|
||||||
|
&& (oldRecommendedRect != newRecommendedRect
|
||||||
|
|| oldChildren != newChildren)
|
||||||
|
) {
|
||||||
|
expectedChildren = newChildren;
|
||||||
d.repositionAll();
|
d.repositionAll();
|
||||||
}
|
}
|
||||||
recommendedRect = newRecommendedRect;
|
recommendedRect = newRecommendedRect;
|
||||||
|
@ -279,13 +286,56 @@ FocusScope {
|
||||||
targetWindow.focus = true;
|
targetWindow.focus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showDesktop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function centerOnVisible(item) {
|
||||||
|
var targetWindow = d.getDesktopWindow(item);
|
||||||
|
if (!targetWindow) {
|
||||||
|
console.warn("Could not find top level window for " + item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof Controller === "undefined") {
|
||||||
|
console.warn("Controller not yet available... can't center");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect();
|
||||||
|
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
||||||
|
newRecommendedRectJS.width,
|
||||||
|
newRecommendedRectJS.height);
|
||||||
|
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
||||||
|
var newX = newRecommendedRect.x + ((newRecommendedRect.width - targetWindow.width) / 2);
|
||||||
|
var newY = newRecommendedRect.y + ((newRecommendedRect.height - targetWindow.height) / 2);
|
||||||
|
targetWindow.x = newX;
|
||||||
|
targetWindow.y = newY;
|
||||||
|
|
||||||
|
// If we've noticed that our recommended desktop rect has changed, record that change here.
|
||||||
|
if (recommendedRect != newRecommendedRect) {
|
||||||
|
recommendedRect = newRecommendedRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function repositionOnVisible(item) {
|
||||||
|
var targetWindow = d.getDesktopWindow(item);
|
||||||
|
if (!targetWindow) {
|
||||||
|
console.warn("Could not find top level window for " + item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof Controller === "undefined") {
|
||||||
|
console.warn("Controller not yet available... can't reposition targetWindow:" + targetWindow);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var oldRecommendedRect = recommendedRect;
|
var oldRecommendedRect = recommendedRect;
|
||||||
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
||||||
var newRecommendedRect = Controller.getRecommendedOverlayRect();
|
var newRecommendedRect = Controller.getRecommendedOverlayRect();
|
||||||
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
||||||
repositionWindow(targetWindow, false, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions);
|
repositionWindow(targetWindow, false, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions);
|
||||||
|
|
||||||
showDesktop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function repositionWindow(targetWindow, forceReposition,
|
function repositionWindow(targetWindow, forceReposition,
|
||||||
|
@ -324,10 +374,8 @@ FocusScope {
|
||||||
}
|
}
|
||||||
var fractionX = Utils.clamp(originRelativeX / oldRecommendedDimmensions.x, 0, 1);
|
var fractionX = Utils.clamp(originRelativeX / oldRecommendedDimmensions.x, 0, 1);
|
||||||
var fractionY = Utils.clamp(originRelativeY / oldRecommendedDimmensions.y, 0, 1);
|
var fractionY = Utils.clamp(originRelativeY / oldRecommendedDimmensions.y, 0, 1);
|
||||||
|
|
||||||
var newX = (fractionX * newRecommendedDimmensions.x) + newRecommendedRect.x;
|
var newX = (fractionX * newRecommendedDimmensions.x) + newRecommendedRect.x;
|
||||||
var newY = (fractionY * newRecommendedDimmensions.y) + newRecommendedRect.y;
|
var newY = (fractionY * newRecommendedDimmensions.y) + newRecommendedRect.y;
|
||||||
|
|
||||||
newPosition = Qt.vector2d(newX, newY);
|
newPosition = Qt.vector2d(newX, newY);
|
||||||
}
|
}
|
||||||
targetWindow.x = newPosition.x;
|
targetWindow.x = newPosition.x;
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
|
//
|
||||||
|
// AvatarBrowser.qml
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 30 Aug 2015
|
||||||
|
// Copyright 2015 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
|
||||||
|
//
|
||||||
|
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
import QtWebEngine 1.1
|
import QtWebEngine 1.1
|
||||||
|
|
||||||
import "../../windows" as Windows
|
import "../../windows-uit" as Windows
|
||||||
import "../../controls" as Controls
|
import "../../controls-uit" as Controls
|
||||||
import "../../styles"
|
import "../../styles-uit"
|
||||||
|
|
||||||
Windows.Window {
|
Windows.Window {
|
||||||
id: root
|
id: root
|
||||||
|
@ -14,20 +24,14 @@ Windows.Window {
|
||||||
modality: Qt.ApplicationModal
|
modality: Qt.ApplicationModal
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
anchors.fill: parent
|
width: pane.contentWidth
|
||||||
|
implicitHeight: pane.scrollHeight
|
||||||
|
|
||||||
Controls.WebView {
|
Controls.WebView {
|
||||||
id: webview
|
id: webview
|
||||||
anchors { top: parent.top; left: parent.left; right: parent.right; bottom: closeButton.top; margins: 8 }
|
anchors.fill: parent
|
||||||
url: "https://metaverse.highfidelity.com/marketplace?category=avatars"
|
url: "https://metaverse.highfidelity.com/marketplace?category=avatars"
|
||||||
focus: true
|
focus: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
|
||||||
id: closeButton
|
|
||||||
anchors { bottom: parent.bottom; right: parent.right; margins: 8 }
|
|
||||||
text: "Close"
|
|
||||||
onClicked: root.destroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ Window {
|
||||||
title: "Running Scripts"
|
title: "Running Scripts"
|
||||||
resizable: true
|
resizable: true
|
||||||
destroyOnInvisible: true
|
destroyOnInvisible: true
|
||||||
x: 40; y: 40
|
|
||||||
implicitWidth: 400
|
implicitWidth: 400
|
||||||
implicitHeight: isHMD ? 695 : 728
|
implicitHeight: isHMD ? 695 : 728
|
||||||
minSize: Qt.vector2d(200, 300)
|
minSize: Qt.vector2d(200, 300)
|
||||||
|
|
|
@ -31,7 +31,7 @@ Fadable {
|
||||||
// decorations can extend outside it.
|
// decorations can extend outside it.
|
||||||
implicitHeight: content ? content.height : 0
|
implicitHeight: content ? content.height : 0
|
||||||
implicitWidth: content ? content.width : 0
|
implicitWidth: content ? content.width : 0
|
||||||
x: -1; y: -1
|
x: desktop.invalid_position; y: desktop.invalid_position;
|
||||||
enabled: visible
|
enabled: visible
|
||||||
|
|
||||||
signal windowDestroyed();
|
signal windowDestroyed();
|
||||||
|
@ -252,6 +252,7 @@ Fadable {
|
||||||
window.parentChanged.connect(raise);
|
window.parentChanged.connect(raise);
|
||||||
raise();
|
raise();
|
||||||
setDefaultFocus();
|
setDefaultFocus();
|
||||||
|
centerOrReposition();
|
||||||
}
|
}
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
window.parentChanged.disconnect(raise); // Prevent warning on shutdown
|
window.parentChanged.disconnect(raise); // Prevent warning on shutdown
|
||||||
|
@ -267,6 +268,18 @@ Fadable {
|
||||||
raise();
|
raise();
|
||||||
}
|
}
|
||||||
enabled = visible
|
enabled = visible
|
||||||
|
|
||||||
|
if (visible && parent) {
|
||||||
|
centerOrReposition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function centerOrReposition() {
|
||||||
|
if (x == desktop.invalid_position && y == desktop.invalid_position) {
|
||||||
|
desktop.centerOnVisible(window);
|
||||||
|
} else {
|
||||||
|
desktop.repositionOnVisible(window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function raise() {
|
function raise() {
|
||||||
|
|
|
@ -19,7 +19,7 @@ Fadable {
|
||||||
// decorations can extend outside it.
|
// decorations can extend outside it.
|
||||||
implicitHeight: content ? content.height : 0
|
implicitHeight: content ? content.height : 0
|
||||||
implicitWidth: content ? content.width : 0
|
implicitWidth: content ? content.width : 0
|
||||||
x: -1; y: -1
|
x: desktop.invalid_position; y: desktop.invalid_position;
|
||||||
enabled: visible
|
enabled: visible
|
||||||
|
|
||||||
signal windowDestroyed();
|
signal windowDestroyed();
|
||||||
|
@ -117,12 +117,21 @@ Fadable {
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
window.parentChanged.connect(raise);
|
window.parentChanged.connect(raise);
|
||||||
raise();
|
raise();
|
||||||
|
centerOrReposition();
|
||||||
}
|
}
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
window.parentChanged.disconnect(raise); // Prevent warning on shutdown
|
window.parentChanged.disconnect(raise); // Prevent warning on shutdown
|
||||||
windowDestroyed();
|
windowDestroyed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function centerOrReposition() {
|
||||||
|
if (x == desktop.invalid_position && y == desktop.invalid_position) {
|
||||||
|
desktop.centerOnVisible(window);
|
||||||
|
} else {
|
||||||
|
desktop.repositionOnVisible(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (!visible && destroyOnInvisible) {
|
if (!visible && destroyOnInvisible) {
|
||||||
destroy();
|
destroy();
|
||||||
|
@ -132,6 +141,10 @@ Fadable {
|
||||||
raise();
|
raise();
|
||||||
}
|
}
|
||||||
enabled = visible
|
enabled = visible
|
||||||
|
|
||||||
|
if (visible && parent) {
|
||||||
|
centerOrReposition();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function raise() {
|
function raise() {
|
||||||
|
|
|
@ -161,7 +161,6 @@ extern "C" {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static QTimer locationUpdateTimer;
|
static QTimer locationUpdateTimer;
|
||||||
static QTimer balanceUpdateTimer;
|
|
||||||
static QTimer identityPacketTimer;
|
static QTimer identityPacketTimer;
|
||||||
static QTimer pingTimer;
|
static QTimer pingTimer;
|
||||||
|
|
||||||
|
@ -211,9 +210,7 @@ const QHash<QString, Application::AcceptURLMethod> Application::_acceptedExtensi
|
||||||
|
|
||||||
class DeadlockWatchdogThread : public QThread {
|
class DeadlockWatchdogThread : public QThread {
|
||||||
public:
|
public:
|
||||||
static const unsigned long HEARTBEAT_CHECK_INTERVAL_SECS = 1;
|
|
||||||
static const unsigned long HEARTBEAT_UPDATE_INTERVAL_SECS = 1;
|
static const unsigned long HEARTBEAT_UPDATE_INTERVAL_SECS = 1;
|
||||||
static const unsigned long HEARTBEAT_REPORT_INTERVAL_USECS = 5 * USECS_PER_SECOND;
|
|
||||||
static const unsigned long MAX_HEARTBEAT_AGE_USECS = 30 * USECS_PER_SECOND;
|
static const unsigned long MAX_HEARTBEAT_AGE_USECS = 30 * USECS_PER_SECOND;
|
||||||
static const int WARNING_ELAPSED_HEARTBEAT = 500 * USECS_PER_MSEC; // warn if elapsed heartbeat average is large
|
static const int WARNING_ELAPSED_HEARTBEAT = 500 * USECS_PER_MSEC; // warn if elapsed heartbeat average is large
|
||||||
static const int HEARTBEAT_SAMPLES = 100000; // ~5 seconds worth of samples
|
static const int HEARTBEAT_SAMPLES = 100000; // ~5 seconds worth of samples
|
||||||
|
@ -240,8 +237,6 @@ public:
|
||||||
*crashTrigger = 0xDEAD10CC;
|
*crashTrigger = 0xDEAD10CC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setSuppressStatus(bool suppress) { _suppressStatus = suppress; }
|
|
||||||
|
|
||||||
void run() override {
|
void run() override {
|
||||||
while (!_quit) {
|
while (!_quit) {
|
||||||
QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS);
|
QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS);
|
||||||
|
@ -249,7 +244,6 @@ public:
|
||||||
uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us
|
uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us
|
||||||
uint64_t now = usecTimestampNow();
|
uint64_t now = usecTimestampNow();
|
||||||
auto lastHeartbeatAge = (now > lastHeartbeat) ? now - lastHeartbeat : 0;
|
auto lastHeartbeatAge = (now > lastHeartbeat) ? now - lastHeartbeat : 0;
|
||||||
auto sinceLastReport = (now > _lastReport) ? now - _lastReport : 0;
|
|
||||||
auto elapsedMovingAverage = _movingAverage.getAverage();
|
auto elapsedMovingAverage = _movingAverage.getAverage();
|
||||||
|
|
||||||
if (elapsedMovingAverage > _maxElapsedAverage) {
|
if (elapsedMovingAverage > _maxElapsedAverage) {
|
||||||
|
@ -275,21 +269,10 @@ public:
|
||||||
if (elapsedMovingAverage > WARNING_ELAPSED_HEARTBEAT) {
|
if (elapsedMovingAverage > WARNING_ELAPSED_HEARTBEAT) {
|
||||||
qDebug() << "DEADLOCK WATCHDOG WARNING:"
|
qDebug() << "DEADLOCK WATCHDOG WARNING:"
|
||||||
<< "lastHeartbeatAge:" << lastHeartbeatAge
|
<< "lastHeartbeatAge:" << lastHeartbeatAge
|
||||||
<< "elapsedMovingAverage:" << elapsedMovingAverage << "** OVER EXPECTED VALUE**"
|
<< "elapsedMovingAverage:" << elapsedMovingAverage << "** OVER EXPECTED VALUE **"
|
||||||
<< "maxElapsed:" << _maxElapsed
|
<< "maxElapsed:" << _maxElapsed
|
||||||
<< "maxElapsedAverage:" << _maxElapsedAverage
|
<< "maxElapsedAverage:" << _maxElapsedAverage
|
||||||
<< "samples:" << _movingAverage.getSamples();
|
<< "samples:" << _movingAverage.getSamples();
|
||||||
_lastReport = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_suppressStatus && sinceLastReport > HEARTBEAT_REPORT_INTERVAL_USECS) {
|
|
||||||
qDebug() << "DEADLOCK WATCHDOG STATUS:"
|
|
||||||
<< "lastHeartbeatAge:" << lastHeartbeatAge
|
|
||||||
<< "elapsedMovingAverage:" << elapsedMovingAverage
|
|
||||||
<< "maxElapsed:" << _maxElapsed
|
|
||||||
<< "maxElapsedAverage:" << _maxElapsedAverage
|
|
||||||
<< "samples:" << _movingAverage.getSamples();
|
|
||||||
_lastReport = now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastHeartbeatAge > MAX_HEARTBEAT_AGE_USECS) {
|
if (lastHeartbeatAge > MAX_HEARTBEAT_AGE_USECS) {
|
||||||
|
@ -311,9 +294,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::atomic<bool> _suppressStatus;
|
|
||||||
static std::atomic<uint64_t> _heartbeat;
|
static std::atomic<uint64_t> _heartbeat;
|
||||||
static std::atomic<uint64_t> _lastReport;
|
|
||||||
static std::atomic<uint64_t> _maxElapsed;
|
static std::atomic<uint64_t> _maxElapsed;
|
||||||
static std::atomic<int> _maxElapsedAverage;
|
static std::atomic<int> _maxElapsedAverage;
|
||||||
static ThreadSafeMovingAverage<int, HEARTBEAT_SAMPLES> _movingAverage;
|
static ThreadSafeMovingAverage<int, HEARTBEAT_SAMPLES> _movingAverage;
|
||||||
|
@ -321,17 +302,11 @@ public:
|
||||||
bool _quit { false };
|
bool _quit { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
std::atomic<bool> DeadlockWatchdogThread::_suppressStatus;
|
|
||||||
std::atomic<uint64_t> DeadlockWatchdogThread::_heartbeat;
|
std::atomic<uint64_t> DeadlockWatchdogThread::_heartbeat;
|
||||||
std::atomic<uint64_t> DeadlockWatchdogThread::_lastReport;
|
|
||||||
std::atomic<uint64_t> DeadlockWatchdogThread::_maxElapsed;
|
std::atomic<uint64_t> DeadlockWatchdogThread::_maxElapsed;
|
||||||
std::atomic<int> DeadlockWatchdogThread::_maxElapsedAverage;
|
std::atomic<int> DeadlockWatchdogThread::_maxElapsedAverage;
|
||||||
ThreadSafeMovingAverage<int, DeadlockWatchdogThread::HEARTBEAT_SAMPLES> DeadlockWatchdogThread::_movingAverage;
|
ThreadSafeMovingAverage<int, DeadlockWatchdogThread::HEARTBEAT_SAMPLES> DeadlockWatchdogThread::_movingAverage;
|
||||||
|
|
||||||
void Application::toggleSuppressDeadlockWatchdogStatus(bool checked) {
|
|
||||||
DeadlockWatchdogThread::setSuppressStatus(checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
class MyNativeEventFilter : public QAbstractNativeEventFilter {
|
class MyNativeEventFilter : public QAbstractNativeEventFilter {
|
||||||
public:
|
public:
|
||||||
|
@ -510,6 +485,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
_sessionRunTimer(startupTimer),
|
_sessionRunTimer(startupTimer),
|
||||||
_previousSessionCrashed(setupEssentials(argc, argv)),
|
_previousSessionCrashed(setupEssentials(argc, argv)),
|
||||||
_undoStackScriptingInterface(&_undoStack),
|
_undoStackScriptingInterface(&_undoStack),
|
||||||
|
_entitySimulation(new PhysicalEntitySimulation()),
|
||||||
_physicsEngine(new PhysicsEngine(Vectors::ZERO)),
|
_physicsEngine(new PhysicsEngine(Vectors::ZERO)),
|
||||||
_entityClipboardRenderer(false, this, this),
|
_entityClipboardRenderer(false, this, this),
|
||||||
_entityClipboard(new EntityTree()),
|
_entityClipboard(new EntityTree()),
|
||||||
|
@ -585,12 +561,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
// put the NodeList and datagram processing on the node thread
|
// put the NodeList and datagram processing on the node thread
|
||||||
nodeList->moveToThread(nodeThread);
|
nodeList->moveToThread(nodeThread);
|
||||||
|
|
||||||
// Model background downloads need to happen on the Datagram Processor Thread. The idle loop will
|
|
||||||
// emit checkBackgroundDownloads to cause the ModelCache to check it's queue for requested background
|
|
||||||
// downloads.
|
|
||||||
auto modelCache = DependencyManager::get<ModelCache>();
|
|
||||||
connect(this, &Application::checkBackgroundDownloads, modelCache.data(), &ModelCache::checkAsynchronousGets);
|
|
||||||
|
|
||||||
// put the audio processing on a separate thread
|
// put the audio processing on a separate thread
|
||||||
QThread* audioThread = new QThread();
|
QThread* audioThread = new QThread();
|
||||||
audioThread->setObjectName("Audio Thread");
|
audioThread->setObjectName("Audio Thread");
|
||||||
|
@ -677,6 +647,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
connect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain,
|
connect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain,
|
||||||
discoverabilityManager.data(), &DiscoverabilityManager::updateLocation);
|
discoverabilityManager.data(), &DiscoverabilityManager::updateLocation);
|
||||||
|
|
||||||
|
// send a location update immediately
|
||||||
|
discoverabilityManager->updateLocation();
|
||||||
|
|
||||||
connect(nodeList.data(), &NodeList::nodeAdded, this, &Application::nodeAdded);
|
connect(nodeList.data(), &NodeList::nodeAdded, this, &Application::nodeAdded);
|
||||||
connect(nodeList.data(), &NodeList::nodeKilled, this, &Application::nodeKilled);
|
connect(nodeList.data(), &NodeList::nodeKilled, this, &Application::nodeKilled);
|
||||||
connect(nodeList.data(), &NodeList::nodeActivated, this, &Application::nodeActivated);
|
connect(nodeList.data(), &NodeList::nodeActivated, this, &Application::nodeActivated);
|
||||||
|
@ -688,13 +661,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
// connect to appropriate slots on AccountManager
|
// connect to appropriate slots on AccountManager
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
|
|
||||||
const qint64 BALANCE_UPDATE_INTERVAL_MSECS = 5 * MSECS_PER_SEC;
|
|
||||||
|
|
||||||
connect(&balanceUpdateTimer, &QTimer::timeout, &accountManager, &AccountManager::updateBalance);
|
|
||||||
balanceUpdateTimer.start(BALANCE_UPDATE_INTERVAL_MSECS);
|
|
||||||
|
|
||||||
connect(&accountManager, &AccountManager::balanceChanged, this, &Application::updateWindowTitle);
|
|
||||||
|
|
||||||
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
||||||
connect(&accountManager, &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
|
connect(&accountManager, &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
|
||||||
connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
|
connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
|
||||||
|
@ -707,9 +673,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
// The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
|
// The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
|
||||||
UserActivityLogger::getInstance().launch(applicationVersion(), _previousSessionCrashed, sessionRunTime.get());
|
UserActivityLogger::getInstance().launch(applicationVersion(), _previousSessionCrashed, sessionRunTime.get());
|
||||||
|
|
||||||
// once the event loop has started, check and signal for an access token
|
|
||||||
QMetaObject::invokeMethod(&accountManager, "checkAndSignalForAccessToken", Qt::QueuedConnection);
|
|
||||||
|
|
||||||
auto addressManager = DependencyManager::get<AddressManager>();
|
auto addressManager = DependencyManager::get<AddressManager>();
|
||||||
|
|
||||||
// use our MyAvatar position and quat for address manager path
|
// use our MyAvatar position and quat for address manager path
|
||||||
|
@ -1123,6 +1086,11 @@ void Application::checkChangeCursor() {
|
||||||
|
|
||||||
_cursorNeedsChanging = false;
|
_cursorNeedsChanging = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// After all of the constructor is completed, then set firstRun to false.
|
||||||
|
Setting::Handle<bool> firstRun{ Settings::firstRun, true };
|
||||||
|
firstRun.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::showCursor(const QCursor& cursor) {
|
void Application::showCursor(const QCursor& cursor) {
|
||||||
|
@ -1197,7 +1165,6 @@ void Application::cleanupBeforeQuit() {
|
||||||
// first stop all timers directly or by invokeMethod
|
// first stop all timers directly or by invokeMethod
|
||||||
// depending on what thread they run in
|
// depending on what thread they run in
|
||||||
locationUpdateTimer.stop();
|
locationUpdateTimer.stop();
|
||||||
balanceUpdateTimer.stop();
|
|
||||||
identityPacketTimer.stop();
|
identityPacketTimer.stop();
|
||||||
pingTimer.stop();
|
pingTimer.stop();
|
||||||
QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection);
|
QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection);
|
||||||
|
@ -1333,8 +1300,6 @@ void Application::initializeGL() {
|
||||||
|
|
||||||
// update before the first render
|
// update before the first render
|
||||||
update(0);
|
update(0);
|
||||||
|
|
||||||
InfoView::show(INFO_HELP_PATH, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameTimingsScriptingInterface _frameTimingsScriptingInterface;
|
FrameTimingsScriptingInterface _frameTimingsScriptingInterface;
|
||||||
|
@ -1511,10 +1476,17 @@ void Application::paintGL() {
|
||||||
|
|
||||||
auto lodManager = DependencyManager::get<LODManager>();
|
auto lodManager = DependencyManager::get<LODManager>();
|
||||||
|
|
||||||
|
{
|
||||||
RenderArgs renderArgs(_gpuContext, getEntities(), getViewFrustum(), lodManager->getOctreeSizeScale(),
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
_viewFrustum.calculate();
|
||||||
|
}
|
||||||
|
RenderArgs renderArgs(_gpuContext, getEntities(), lodManager->getOctreeSizeScale(),
|
||||||
lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
|
lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
|
||||||
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
||||||
|
{
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
renderArgs.setViewFrustum(_viewFrustum);
|
||||||
|
}
|
||||||
|
|
||||||
PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
|
PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
@ -1681,7 +1653,7 @@ void Application::paintGL() {
|
||||||
renderArgs._context->enableStereo(true);
|
renderArgs._context->enableStereo(true);
|
||||||
mat4 eyeOffsets[2];
|
mat4 eyeOffsets[2];
|
||||||
mat4 eyeProjections[2];
|
mat4 eyeProjections[2];
|
||||||
auto baseProjection = renderArgs._viewFrustum->getProjection();
|
auto baseProjection = renderArgs.getViewFrustum().getProjection();
|
||||||
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
||||||
float IPDScale = hmdInterface->getIPDScale();
|
float IPDScale = hmdInterface->getIPDScale();
|
||||||
mat4 headPose = displayPlugin->getHeadPose();
|
mat4 headPose = displayPlugin->getHeadPose();
|
||||||
|
@ -1811,7 +1783,10 @@ void Application::resizeGL() {
|
||||||
_myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), aspectRatio,
|
_myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), aspectRatio,
|
||||||
DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||||
// Possible change in aspect ratio
|
// Possible change in aspect ratio
|
||||||
loadViewFrustum(_myCamera, _viewFrustum);
|
{
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
loadViewFrustum(_myCamera, _viewFrustum);
|
||||||
|
}
|
||||||
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
auto uiSize = displayPlugin->getRecommendedUiSize();
|
auto uiSize = displayPlugin->getRecommendedUiSize();
|
||||||
|
@ -2138,6 +2113,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
|
|
||||||
case Qt::Key_J:
|
case Qt::Key_J:
|
||||||
if (isShifted) {
|
if (isShifted) {
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() - 0.1f);
|
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() - 0.1f);
|
||||||
} else {
|
} else {
|
||||||
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(-0.001, 0, 0));
|
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(-0.001, 0, 0));
|
||||||
|
@ -2147,6 +2123,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
|
|
||||||
case Qt::Key_M:
|
case Qt::Key_M:
|
||||||
if (isShifted) {
|
if (isShifted) {
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() + 0.1f);
|
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() + 0.1f);
|
||||||
} else {
|
} else {
|
||||||
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0.001, 0, 0));
|
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0.001, 0, 0));
|
||||||
|
@ -2752,9 +2729,6 @@ void Application::idle(uint64_t now) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_overlayConductor.update(secondsSinceLastUpdate);
|
_overlayConductor.update(secondsSinceLastUpdate);
|
||||||
|
|
||||||
// check for any requested background downloads.
|
|
||||||
emit checkBackgroundDownloads();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setLowVelocityFilter(bool lowVelocityFilter) {
|
void Application::setLowVelocityFilter(bool lowVelocityFilter) {
|
||||||
|
@ -2985,7 +2959,21 @@ void Application::init() {
|
||||||
addressLookupString = arguments().value(urlIndex + 1);
|
addressLookupString = arguments().value(urlIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
DependencyManager::get<AddressManager>()->loadSettings(addressLookupString);
|
Setting::Handle<bool> firstRun { Settings::firstRun, true };
|
||||||
|
if (addressLookupString.isEmpty() && firstRun.get()) {
|
||||||
|
qDebug() << "First run and no URL passed... attempting to go to Home or Entry...";
|
||||||
|
DependencyManager::get<AddressManager>()->ifLocalSandboxRunningElse([](){
|
||||||
|
qDebug() << "Home sandbox appears to be running, going to Home.";
|
||||||
|
DependencyManager::get<AddressManager>()->goToLocalSandbox();
|
||||||
|
},
|
||||||
|
[](){
|
||||||
|
qDebug() << "Home sandbox does not appear to be running, going to Entry.";
|
||||||
|
DependencyManager::get<AddressManager>()->goToEntry();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
qDebug() << "Not first run... going to" << qPrintable(addressLookupString.isEmpty() ? QString("previous location") : addressLookupString);
|
||||||
|
DependencyManager::get<AddressManager>()->loadSettings(addressLookupString);
|
||||||
|
}
|
||||||
|
|
||||||
qCDebug(interfaceapp) << "Loaded settings";
|
qCDebug(interfaceapp) << "Loaded settings";
|
||||||
|
|
||||||
|
@ -2995,19 +2983,22 @@ void Application::init() {
|
||||||
DependencyManager::get<NodeList>()->sendDomainServerCheckIn();
|
DependencyManager::get<NodeList>()->sendDomainServerCheckIn();
|
||||||
|
|
||||||
getEntities()->init();
|
getEntities()->init();
|
||||||
getEntities()->setViewFrustum(getViewFrustum());
|
{
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
getEntities()->setViewFrustum(_viewFrustum);
|
||||||
|
}
|
||||||
|
|
||||||
ObjectMotionState::setShapeManager(&_shapeManager);
|
ObjectMotionState::setShapeManager(&_shapeManager);
|
||||||
_physicsEngine->init();
|
_physicsEngine->init();
|
||||||
|
|
||||||
EntityTreePointer tree = getEntities()->getTree();
|
EntityTreePointer tree = getEntities()->getTree();
|
||||||
_entitySimulation.init(tree, _physicsEngine, &_entityEditSender);
|
_entitySimulation->init(tree, _physicsEngine, &_entityEditSender);
|
||||||
tree->setSimulation(&_entitySimulation);
|
tree->setSimulation(_entitySimulation);
|
||||||
|
|
||||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
|
|
||||||
// connect the _entityCollisionSystem to our EntityTreeRenderer since that's what handles running entity scripts
|
// connect the _entityCollisionSystem to our EntityTreeRenderer since that's what handles running entity scripts
|
||||||
connect(&_entitySimulation, &EntitySimulation::entityCollisionWithEntity,
|
connect(_entitySimulation.get(), &EntitySimulation::entityCollisionWithEntity,
|
||||||
getEntities(), &EntityTreeRenderer::entityCollisionWithEntity);
|
getEntities(), &EntityTreeRenderer::entityCollisionWithEntity);
|
||||||
|
|
||||||
// connect the _entities (EntityTreeRenderer) to our script engine's EntityScriptingInterface for firing
|
// connect the _entities (EntityTreeRenderer) to our script engine's EntityScriptingInterface for firing
|
||||||
|
@ -3015,12 +3006,26 @@ void Application::init() {
|
||||||
getEntities()->connectSignalsToSlots(entityScriptingInterface.data());
|
getEntities()->connectSignalsToSlots(entityScriptingInterface.data());
|
||||||
|
|
||||||
_entityClipboardRenderer.init();
|
_entityClipboardRenderer.init();
|
||||||
_entityClipboardRenderer.setViewFrustum(getViewFrustum());
|
{
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
_entityClipboardRenderer.setViewFrustum(_viewFrustum);
|
||||||
|
}
|
||||||
_entityClipboardRenderer.setTree(_entityClipboard);
|
_entityClipboardRenderer.setTree(_entityClipboard);
|
||||||
|
|
||||||
// Make sure any new sounds are loaded as soon as know about them.
|
// Make sure any new sounds are loaded as soon as know about them.
|
||||||
connect(tree.get(), &EntityTree::newCollisionSoundURL, DependencyManager::get<SoundCache>().data(), &SoundCache::getSound);
|
connect(tree.get(), &EntityTree::newCollisionSoundURL, this, [this](QUrl newURL, EntityItemID id) {
|
||||||
connect(getMyAvatar(), &MyAvatar::newCollisionSoundURL, DependencyManager::get<SoundCache>().data(), &SoundCache::getSound);
|
EntityTreePointer tree = getEntities()->getTree();
|
||||||
|
if (auto entity = tree->findEntityByEntityItemID(id)) {
|
||||||
|
auto sound = DependencyManager::get<SoundCache>()->getSound(newURL);
|
||||||
|
entity->setCollisionSound(sound);
|
||||||
|
}
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
|
connect(getMyAvatar(), &MyAvatar::newCollisionSoundURL, this, [this](QUrl newURL) {
|
||||||
|
if (auto avatar = getMyAvatar()) {
|
||||||
|
auto sound = DependencyManager::get<SoundCache>()->getSound(newURL);
|
||||||
|
avatar->setCollisionSound(sound);
|
||||||
|
}
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updateLOD() const {
|
void Application::updateLOD() const {
|
||||||
|
@ -3218,9 +3223,12 @@ void Application::resetPhysicsReadyInformation() {
|
||||||
|
|
||||||
void Application::reloadResourceCaches() {
|
void Application::reloadResourceCaches() {
|
||||||
resetPhysicsReadyInformation();
|
resetPhysicsReadyInformation();
|
||||||
|
{
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
_viewFrustum.setPosition(glm::vec3(0.0f, 0.0f, TREE_SCALE));
|
||||||
|
_viewFrustum.setOrientation(glm::quat());
|
||||||
|
}
|
||||||
// Clear entities out of view frustum
|
// Clear entities out of view frustum
|
||||||
_viewFrustum.setPosition(glm::vec3(0.0f, 0.0f, TREE_SCALE));
|
|
||||||
_viewFrustum.setOrientation(glm::quat());
|
|
||||||
queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions);
|
queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions);
|
||||||
|
|
||||||
DependencyManager::get<AssetClient>()->clearCache();
|
DependencyManager::get<AssetClient>()->clearCache();
|
||||||
|
@ -3410,22 +3418,22 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
PerformanceTimer perfTimer("updateStates)");
|
PerformanceTimer perfTimer("updateStates)");
|
||||||
static VectorOfMotionStates motionStates;
|
static VectorOfMotionStates motionStates;
|
||||||
_entitySimulation.getObjectsToRemoveFromPhysics(motionStates);
|
_entitySimulation->getObjectsToRemoveFromPhysics(motionStates);
|
||||||
_physicsEngine->removeObjects(motionStates);
|
_physicsEngine->removeObjects(motionStates);
|
||||||
_entitySimulation.deleteObjectsRemovedFromPhysics();
|
_entitySimulation->deleteObjectsRemovedFromPhysics();
|
||||||
|
|
||||||
getEntities()->getTree()->withReadLock([&] {
|
getEntities()->getTree()->withReadLock([&] {
|
||||||
_entitySimulation.getObjectsToAddToPhysics(motionStates);
|
_entitySimulation->getObjectsToAddToPhysics(motionStates);
|
||||||
_physicsEngine->addObjects(motionStates);
|
_physicsEngine->addObjects(motionStates);
|
||||||
|
|
||||||
});
|
});
|
||||||
getEntities()->getTree()->withReadLock([&] {
|
getEntities()->getTree()->withReadLock([&] {
|
||||||
_entitySimulation.getObjectsToChange(motionStates);
|
_entitySimulation->getObjectsToChange(motionStates);
|
||||||
VectorOfMotionStates stillNeedChange = _physicsEngine->changeObjects(motionStates);
|
VectorOfMotionStates stillNeedChange = _physicsEngine->changeObjects(motionStates);
|
||||||
_entitySimulation.setObjectsToChange(stillNeedChange);
|
_entitySimulation->setObjectsToChange(stillNeedChange);
|
||||||
});
|
});
|
||||||
|
|
||||||
_entitySimulation.applyActionChanges();
|
_entitySimulation->applyActionChanges();
|
||||||
|
|
||||||
avatarManager->getObjectsToRemoveFromPhysics(motionStates);
|
avatarManager->getObjectsToRemoveFromPhysics(motionStates);
|
||||||
_physicsEngine->removeObjects(motionStates);
|
_physicsEngine->removeObjects(motionStates);
|
||||||
|
@ -3453,7 +3461,7 @@ void Application::update(float deltaTime) {
|
||||||
getEntities()->getTree()->withWriteLock([&] {
|
getEntities()->getTree()->withWriteLock([&] {
|
||||||
PerformanceTimer perfTimer("handleOutgoingChanges");
|
PerformanceTimer perfTimer("handleOutgoingChanges");
|
||||||
const VectorOfMotionStates& outgoingChanges = _physicsEngine->getOutgoingChanges();
|
const VectorOfMotionStates& outgoingChanges = _physicsEngine->getOutgoingChanges();
|
||||||
_entitySimulation.handleOutgoingChanges(outgoingChanges);
|
_entitySimulation->handleOutgoingChanges(outgoingChanges);
|
||||||
avatarManager->handleOutgoingChanges(outgoingChanges);
|
avatarManager->handleOutgoingChanges(outgoingChanges);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3466,7 +3474,7 @@ void Application::update(float deltaTime) {
|
||||||
PerformanceTimer perfTimer("entities");
|
PerformanceTimer perfTimer("entities");
|
||||||
// Collision events (and their scripts) must not be handled when we're locked, above. (That would risk
|
// Collision events (and their scripts) must not be handled when we're locked, above. (That would risk
|
||||||
// deadlock.)
|
// deadlock.)
|
||||||
_entitySimulation.handleCollisionEvents(collisionEvents);
|
_entitySimulation->handleCollisionEvents(collisionEvents);
|
||||||
|
|
||||||
// NOTE: the getEntities()->update() call below will wait for lock
|
// NOTE: the getEntities()->update() call below will wait for lock
|
||||||
// and will simulate entity motion (the EntityTree has been given an EntitySimulation).
|
// and will simulate entity motion (the EntityTree has been given an EntitySimulation).
|
||||||
|
@ -3509,7 +3517,7 @@ void Application::update(float deltaTime) {
|
||||||
// actually need to calculate the view frustum planes to send these details
|
// actually need to calculate the view frustum planes to send these details
|
||||||
// to the server.
|
// to the server.
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("loadViewFrustum");
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
loadViewFrustum(_myCamera, _viewFrustum);
|
loadViewFrustum(_myCamera, _viewFrustum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3518,6 +3526,7 @@ void Application::update(float deltaTime) {
|
||||||
// Update my voxel servers with my current voxel query...
|
// Update my voxel servers with my current voxel query...
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("QueryOctree", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE_EX("QueryOctree", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
PerformanceTimer perfTimer("queryOctree");
|
PerformanceTimer perfTimer("queryOctree");
|
||||||
quint64 sinceLastQuery = now - _lastQueriedTime;
|
quint64 sinceLastQuery = now - _lastQueriedTime;
|
||||||
const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND;
|
const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND;
|
||||||
|
@ -3629,14 +3638,16 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
||||||
//qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView();
|
//qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView();
|
||||||
bool wantExtraDebugging = getLogger()->extraDebugging();
|
bool wantExtraDebugging = getLogger()->extraDebugging();
|
||||||
|
|
||||||
_octreeQuery.setCameraPosition(_viewFrustum.getPosition());
|
ViewFrustum viewFrustum;
|
||||||
_octreeQuery.setCameraOrientation(_viewFrustum.getOrientation());
|
copyViewFrustum(viewFrustum);
|
||||||
_octreeQuery.setCameraFov(_viewFrustum.getFieldOfView());
|
_octreeQuery.setCameraPosition(viewFrustum.getPosition());
|
||||||
_octreeQuery.setCameraAspectRatio(_viewFrustum.getAspectRatio());
|
_octreeQuery.setCameraOrientation(viewFrustum.getOrientation());
|
||||||
_octreeQuery.setCameraNearClip(_viewFrustum.getNearClip());
|
_octreeQuery.setCameraFov(viewFrustum.getFieldOfView());
|
||||||
_octreeQuery.setCameraFarClip(_viewFrustum.getFarClip());
|
_octreeQuery.setCameraAspectRatio(viewFrustum.getAspectRatio());
|
||||||
|
_octreeQuery.setCameraNearClip(viewFrustum.getNearClip());
|
||||||
|
_octreeQuery.setCameraFarClip(viewFrustum.getFarClip());
|
||||||
_octreeQuery.setCameraEyeOffsetPosition(glm::vec3());
|
_octreeQuery.setCameraEyeOffsetPosition(glm::vec3());
|
||||||
_octreeQuery.setCameraCenterRadius(_viewFrustum.getCenterRadius());
|
_octreeQuery.setCameraCenterRadius(viewFrustum.getCenterRadius());
|
||||||
auto lodManager = DependencyManager::get<LODManager>();
|
auto lodManager = DependencyManager::get<LODManager>();
|
||||||
_octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale());
|
_octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale());
|
||||||
_octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust());
|
_octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust());
|
||||||
|
@ -3672,7 +3683,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
||||||
rootDetails.y * TREE_SCALE,
|
rootDetails.y * TREE_SCALE,
|
||||||
rootDetails.z * TREE_SCALE) - glm::vec3(HALF_TREE_SCALE),
|
rootDetails.z * TREE_SCALE) - glm::vec3(HALF_TREE_SCALE),
|
||||||
rootDetails.s * TREE_SCALE);
|
rootDetails.s * TREE_SCALE);
|
||||||
if (_viewFrustum.cubeIntersectsKeyhole(serverBounds)) {
|
if (viewFrustum.cubeIntersectsKeyhole(serverBounds)) {
|
||||||
inViewServers++;
|
inViewServers++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3738,11 +3749,9 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
||||||
rootDetails.s * TREE_SCALE);
|
rootDetails.s * TREE_SCALE);
|
||||||
|
|
||||||
|
|
||||||
inView = _viewFrustum.cubeIntersectsKeyhole(serverBounds);
|
inView = viewFrustum.cubeIntersectsKeyhole(serverBounds);
|
||||||
} else {
|
} else if (wantExtraDebugging) {
|
||||||
if (wantExtraDebugging) {
|
qCDebug(interfaceapp) << "Jurisdiction without RootCode for node " << *node << ". That's unusual!";
|
||||||
qCDebug(interfaceapp) << "Jurisdiction without RootCode for node " << *node << ". That's unusual!";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3833,6 +3842,7 @@ QRect Application::getDesirableApplicationGeometry() const {
|
||||||
// or the "myCamera".
|
// or the "myCamera".
|
||||||
//
|
//
|
||||||
void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
||||||
|
PerformanceTimer perfTimer("loadViewFrustum");
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
// We will use these below, from either the camera or head vectors calculated above
|
// We will use these below, from either the camera or head vectors calculated above
|
||||||
viewFrustum.setProjection(camera.getProjection());
|
viewFrustum.setProjection(camera.getProjection());
|
||||||
|
@ -3861,7 +3871,8 @@ PickRay Application::computePickRay(float x, float y) const {
|
||||||
getApplicationCompositor().computeHmdPickRay(pickPoint, result.origin, result.direction);
|
getApplicationCompositor().computeHmdPickRay(pickPoint, result.origin, result.direction);
|
||||||
} else {
|
} else {
|
||||||
pickPoint /= getCanvasSize();
|
pickPoint /= getCanvasSize();
|
||||||
getViewFrustum()->computePickRay(pickPoint.x, pickPoint.y, result.origin, result.direction);
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
_viewFrustum.computePickRay(pickPoint.x, pickPoint.y, result.origin, result.direction);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -3874,44 +3885,19 @@ glm::vec3 Application::getAvatarPosition() const {
|
||||||
return getMyAvatar()->getPosition();
|
return getMyAvatar()->getPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewFrustum* Application::getViewFrustum() {
|
void Application::copyViewFrustum(ViewFrustum& viewOut) const {
|
||||||
#ifdef DEBUG
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
if (QThread::currentThread() == activeRenderingThread) {
|
viewOut = _viewFrustum;
|
||||||
// FIXME, figure out a better way to do this
|
|
||||||
//qWarning() << "Calling Application::getViewFrustum() from the active rendering thread, did you mean Application::getDisplayViewFrustum()?";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return &_viewFrustum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ViewFrustum* Application::getViewFrustum() const {
|
void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const {
|
||||||
#ifdef DEBUG
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
if (QThread::currentThread() == activeRenderingThread) {
|
viewOut = _displayViewFrustum;
|
||||||
// FIXME, figure out a better way to do this
|
|
||||||
//qWarning() << "Calling Application::getViewFrustum() from the active rendering thread, did you mean Application::getDisplayViewFrustum()?";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return &_viewFrustum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewFrustum* Application::getDisplayViewFrustum() {
|
void Application::copyShadowViewFrustum(ViewFrustum& viewOut) const {
|
||||||
#ifdef DEBUG
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
if (QThread::currentThread() != activeRenderingThread) {
|
viewOut = _shadowViewFrustum;
|
||||||
// FIXME, figure out a better way to do this
|
|
||||||
// qWarning() << "Calling Application::getDisplayViewFrustum() from outside the active rendering thread or outside rendering, did you mean Application::getViewFrustum()?";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return &_displayViewFrustum;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ViewFrustum* Application::getDisplayViewFrustum() const {
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (QThread::currentThread() != activeRenderingThread) {
|
|
||||||
// FIXME, figure out a better way to do this
|
|
||||||
// qWarning() << "Calling Application::getDisplayViewFrustum() from outside the active rendering thread or outside rendering, did you mean Application::getViewFrustum()?";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return &_displayViewFrustum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WorldBox Render Data & rendering functions
|
// WorldBox Render Data & rendering functions
|
||||||
|
@ -3976,7 +3962,7 @@ namespace render {
|
||||||
auto skybox = skyStage->getSkybox();
|
auto skybox = skyStage->getSkybox();
|
||||||
if (skybox) {
|
if (skybox) {
|
||||||
PerformanceTimer perfTimer("skybox");
|
PerformanceTimer perfTimer("skybox");
|
||||||
skybox->render(batch, *(args->_viewFrustum));
|
skybox->render(batch, args->getViewFrustum());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4020,7 +4006,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
||||||
|
|
||||||
// load the view frustum
|
// load the view frustum
|
||||||
loadViewFrustum(theCamera, _displayViewFrustum);
|
{
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
loadViewFrustum(theCamera, _displayViewFrustum);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO fix shadows and make them use the GPU library
|
// TODO fix shadows and make them use the GPU library
|
||||||
|
|
||||||
|
@ -4088,7 +4077,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("EngineRun");
|
PerformanceTimer perfTimer("EngineRun");
|
||||||
|
|
||||||
renderArgs->_viewFrustum = getDisplayViewFrustum();
|
{
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
renderArgs->setViewFrustum(_displayViewFrustum);
|
||||||
|
}
|
||||||
_renderEngine->getRenderContext()->args = renderArgs;
|
_renderEngine->getRenderContext()->args = renderArgs;
|
||||||
|
|
||||||
// Before the deferred pass, let's try to use the render engine
|
// Before the deferred pass, let's try to use the render engine
|
||||||
|
@ -4315,6 +4307,7 @@ void Application::nodeKilled(SharedNodePointer node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::trackIncomingOctreePacket(ReceivedMessage& message, SharedNodePointer sendingNode, bool wasStatsPacket) {
|
void Application::trackIncomingOctreePacket(ReceivedMessage& message, SharedNodePointer sendingNode, bool wasStatsPacket) {
|
||||||
// Attempt to identify the sender from its address.
|
// Attempt to identify the sender from its address.
|
||||||
if (sendingNode) {
|
if (sendingNode) {
|
||||||
|
@ -4956,24 +4949,19 @@ qreal Application::getDevicePixelRatio() {
|
||||||
return (_window && _window->windowHandle()) ? _window->windowHandle()->devicePixelRatio() : 1.0;
|
return (_window && _window->windowHandle()) ? _window->windowHandle()->devicePixelRatio() : 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayPlugin* Application::getActiveDisplayPlugin() {
|
DisplayPluginPointer Application::getActiveDisplayPlugin() const {
|
||||||
DisplayPlugin* result = nullptr;
|
if (QThread::currentThread() != thread()) {
|
||||||
if (QThread::currentThread() == thread()) {
|
|
||||||
if (nullptr == _displayPlugin) {
|
|
||||||
updateDisplayMode();
|
|
||||||
Q_ASSERT(_displayPlugin);
|
|
||||||
}
|
|
||||||
result = _displayPlugin.get();
|
|
||||||
} else {
|
|
||||||
std::unique_lock<std::mutex> lock(_displayPluginLock);
|
std::unique_lock<std::mutex> lock(_displayPluginLock);
|
||||||
result = _displayPlugin.get();
|
return _displayPlugin;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
|
if (!_displayPlugin) {
|
||||||
|
const_cast<Application*>(this)->updateDisplayMode();
|
||||||
|
Q_ASSERT(_displayPlugin);
|
||||||
|
}
|
||||||
|
return _displayPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DisplayPlugin* Application::getActiveDisplayPlugin() const {
|
|
||||||
return const_cast<Application*>(this)->getActiveDisplayPlugin();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) {
|
static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) {
|
||||||
auto menu = Menu::getInstance();
|
auto menu = Menu::getInstance();
|
||||||
|
@ -5217,10 +5205,10 @@ void Application::updateInputModes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
mat4 Application::getEyeProjection(int eye) const {
|
mat4 Application::getEyeProjection(int eye) const {
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
if (isHMDMode()) {
|
if (isHMDMode()) {
|
||||||
return getActiveDisplayPlugin()->getEyeProjection((Eye)eye, _viewFrustum.getProjection());
|
return getActiveDisplayPlugin()->getEyeProjection((Eye)eye, _viewFrustum.getProjection());
|
||||||
}
|
}
|
||||||
|
|
||||||
return _viewFrustum.getProjection();
|
return _viewFrustum.getProjection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,14 +128,12 @@ public:
|
||||||
Camera* getCamera() { return &_myCamera; }
|
Camera* getCamera() { return &_myCamera; }
|
||||||
const Camera* getCamera() const { return &_myCamera; }
|
const Camera* getCamera() const { return &_myCamera; }
|
||||||
// Represents the current view frustum of the avatar.
|
// Represents the current view frustum of the avatar.
|
||||||
ViewFrustum* getViewFrustum();
|
void copyViewFrustum(ViewFrustum& viewOut) const;
|
||||||
const ViewFrustum* getViewFrustum() const;
|
|
||||||
// Represents the view frustum of the current rendering pass,
|
// Represents the view frustum of the current rendering pass,
|
||||||
// which might be different from the viewFrustum, i.e. shadowmap
|
// which might be different from the viewFrustum, i.e. shadowmap
|
||||||
// passes, mirror window passes, etc
|
// passes, mirror window passes, etc
|
||||||
ViewFrustum* getDisplayViewFrustum();
|
void copyDisplayViewFrustum(ViewFrustum& viewOut) const;
|
||||||
const ViewFrustum* getDisplayViewFrustum() const;
|
void copyShadowViewFrustum(ViewFrustum& viewOut) const override;
|
||||||
ViewFrustum* getShadowViewFrustum() override { return &_shadowViewFrustum; }
|
|
||||||
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
|
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
|
||||||
EntityTreeRenderer* getEntities() const { return DependencyManager::get<EntityTreeRenderer>().data(); }
|
EntityTreeRenderer* getEntities() const { return DependencyManager::get<EntityTreeRenderer>().data(); }
|
||||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||||
|
@ -169,7 +167,7 @@ public:
|
||||||
virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; }
|
virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; }
|
||||||
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) override;
|
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) override;
|
||||||
|
|
||||||
virtual ViewFrustum* getCurrentViewFrustum() override { return getDisplayViewFrustum(); }
|
virtual void copyCurrentViewFrustum(ViewFrustum& viewOut) const override { copyDisplayViewFrustum(viewOut); }
|
||||||
virtual QThread* getMainThread() override { return thread(); }
|
virtual QThread* getMainThread() override { return thread(); }
|
||||||
virtual PickRay computePickRay(float x, float y) const override;
|
virtual PickRay computePickRay(float x, float y) const override;
|
||||||
virtual glm::vec3 getAvatarPosition() const override;
|
virtual glm::vec3 getAvatarPosition() const override;
|
||||||
|
@ -177,8 +175,7 @@ public:
|
||||||
|
|
||||||
void setActiveDisplayPlugin(const QString& pluginName);
|
void setActiveDisplayPlugin(const QString& pluginName);
|
||||||
|
|
||||||
DisplayPlugin* getActiveDisplayPlugin();
|
DisplayPluginPointer getActiveDisplayPlugin() const;
|
||||||
const DisplayPlugin* getActiveDisplayPlugin() const;
|
|
||||||
|
|
||||||
FileLogger* getLogger() const { return _logger; }
|
FileLogger* getLogger() const { return _logger; }
|
||||||
|
|
||||||
|
@ -224,8 +221,6 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void svoImportRequested(const QString& url);
|
void svoImportRequested(const QString& url);
|
||||||
|
|
||||||
void checkBackgroundDownloads();
|
|
||||||
|
|
||||||
void fullAvatarURLChanged(const QString& newValue, const QString& modelName);
|
void fullAvatarURLChanged(const QString& newValue, const QString& modelName);
|
||||||
|
|
||||||
void beforeAboutToQuit();
|
void beforeAboutToQuit();
|
||||||
|
@ -255,7 +250,6 @@ public slots:
|
||||||
|
|
||||||
void resetSensors(bool andReload = false);
|
void resetSensors(bool andReload = false);
|
||||||
void setActiveFaceTracker() const;
|
void setActiveFaceTracker() const;
|
||||||
void toggleSuppressDeadlockWatchdogStatus(bool checked);
|
|
||||||
|
|
||||||
#ifdef HAVE_IVIEWHMD
|
#ifdef HAVE_IVIEWHMD
|
||||||
void setActiveEyeTracker();
|
void setActiveEyeTracker();
|
||||||
|
@ -388,7 +382,7 @@ private:
|
||||||
|
|
||||||
OffscreenGLCanvas* _offscreenContext { nullptr };
|
OffscreenGLCanvas* _offscreenContext { nullptr };
|
||||||
DisplayPluginPointer _displayPlugin;
|
DisplayPluginPointer _displayPlugin;
|
||||||
std::mutex _displayPluginLock;
|
mutable std::mutex _displayPluginLock;
|
||||||
InputPluginList _activeInputPlugins;
|
InputPluginList _activeInputPlugins;
|
||||||
|
|
||||||
bool _activatingDisplayPlugin { false };
|
bool _activatingDisplayPlugin { false };
|
||||||
|
@ -408,12 +402,13 @@ private:
|
||||||
QElapsedTimer _lastTimeUpdated;
|
QElapsedTimer _lastTimeUpdated;
|
||||||
|
|
||||||
ShapeManager _shapeManager;
|
ShapeManager _shapeManager;
|
||||||
PhysicalEntitySimulation _entitySimulation;
|
PhysicalEntitySimulationPointer _entitySimulation;
|
||||||
PhysicsEnginePointer _physicsEngine;
|
PhysicsEnginePointer _physicsEngine;
|
||||||
|
|
||||||
EntityTreeRenderer _entityClipboardRenderer;
|
EntityTreeRenderer _entityClipboardRenderer;
|
||||||
EntityTreePointer _entityClipboard;
|
EntityTreePointer _entityClipboard;
|
||||||
|
|
||||||
|
mutable QMutex _viewMutex { QMutex::Recursive };
|
||||||
ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc.
|
ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc.
|
||||||
ViewFrustum _lastQueriedViewFrustum; /// last view frustum used to query octree servers (voxels)
|
ViewFrustum _lastQueriedViewFrustum; /// last view frustum used to query octree servers (voxels)
|
||||||
ViewFrustum _displayViewFrustum;
|
ViewFrustum _displayViewFrustum;
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
#include "Bookmarks.h"
|
#include "Bookmarks.h"
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
|
|
||||||
|
|
||||||
|
const QString Bookmarks::HOME_BOOKMARK = "Home";
|
||||||
|
|
||||||
|
|
||||||
Bookmarks::Bookmarks() {
|
Bookmarks::Bookmarks() {
|
||||||
_bookmarksFilename = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + BOOKMARKS_FILENAME;
|
_bookmarksFilename = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + BOOKMARKS_FILENAME;
|
||||||
readFromFile();
|
readFromFile();
|
||||||
|
@ -60,6 +64,10 @@ bool Bookmarks::contains(const QString& name) const {
|
||||||
return _bookmarks.contains(name);
|
return _bookmarks.contains(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Bookmarks::addressForBookmark(const QString& name) const {
|
||||||
|
return _bookmarks.value(name).toString();
|
||||||
|
}
|
||||||
|
|
||||||
void Bookmarks::readFromFile() {
|
void Bookmarks::readFromFile() {
|
||||||
QFile loadFile(_bookmarksFilename);
|
QFile loadFile(_bookmarksFilename);
|
||||||
|
|
||||||
|
@ -95,6 +103,8 @@ void Bookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) {
|
||||||
// Add menus/actions
|
// Add menus/actions
|
||||||
auto bookmarkAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::BookmarkLocation);
|
auto bookmarkAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::BookmarkLocation);
|
||||||
QObject::connect(bookmarkAction, SIGNAL(triggered()), this, SLOT(bookmarkLocation()), Qt::QueuedConnection);
|
QObject::connect(bookmarkAction, SIGNAL(triggered()), this, SLOT(bookmarkLocation()), Qt::QueuedConnection);
|
||||||
|
auto setHomeAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::SetHomeLocation);
|
||||||
|
QObject::connect(setHomeAction, SIGNAL(triggered()), this, SLOT(setHomeLocation()), Qt::QueuedConnection);
|
||||||
_bookmarksMenu = menu->addMenu(MenuOption::Bookmarks);
|
_bookmarksMenu = menu->addMenu(MenuOption::Bookmarks);
|
||||||
_deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteBookmark);
|
_deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteBookmark);
|
||||||
QObject::connect(_deleteBookmarksAction, SIGNAL(triggered()), this, SLOT(deleteBookmark()), Qt::QueuedConnection);
|
QObject::connect(_deleteBookmarksAction, SIGNAL(triggered()), this, SLOT(deleteBookmark()), Qt::QueuedConnection);
|
||||||
|
@ -146,6 +156,18 @@ void Bookmarks::bookmarkLocation() {
|
||||||
enableMenuItems(true);
|
enableMenuItems(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bookmarks::setHomeLocation() {
|
||||||
|
Menu* menubar = Menu::getInstance();
|
||||||
|
QString bookmarkName = HOME_BOOKMARK;
|
||||||
|
auto addressManager = DependencyManager::get<AddressManager>();
|
||||||
|
QString bookmarkAddress = addressManager->currentAddress().toString();
|
||||||
|
|
||||||
|
addLocationToMenu(menubar, bookmarkName, bookmarkAddress);
|
||||||
|
insert(bookmarkName, bookmarkAddress); // Overwrites any item with the same bookmarkName.
|
||||||
|
|
||||||
|
enableMenuItems(true);
|
||||||
|
}
|
||||||
|
|
||||||
void Bookmarks::teleportToBookmark() {
|
void Bookmarks::teleportToBookmark() {
|
||||||
QAction* action = qobject_cast<QAction*>(sender());
|
QAction* action = qobject_cast<QAction*>(sender());
|
||||||
QString address = action->data().toString();
|
QString address = action->data().toString();
|
||||||
|
|
|
@ -29,8 +29,13 @@ public:
|
||||||
|
|
||||||
void setupMenus(Menu* menubar, MenuWrapper* menu);
|
void setupMenus(Menu* menubar, MenuWrapper* menu);
|
||||||
|
|
||||||
|
QString addressForBookmark(const QString& name) const;
|
||||||
|
|
||||||
|
static const QString HOME_BOOKMARK;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void bookmarkLocation();
|
void bookmarkLocation();
|
||||||
|
void setHomeLocation();
|
||||||
void teleportToBookmark();
|
void teleportToBookmark();
|
||||||
void deleteBookmark();
|
void deleteBookmark();
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,13 @@
|
||||||
#include <AddressManager.h>
|
#include <AddressManager.h>
|
||||||
#include <DomainHandler.h>
|
#include <DomainHandler.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
|
#include <UserActivityLogger.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
|
|
||||||
#include "DiscoverabilityManager.h"
|
#include "DiscoverabilityManager.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
|
|
||||||
const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::All;
|
const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::Friends;
|
||||||
|
|
||||||
DiscoverabilityManager::DiscoverabilityManager() :
|
DiscoverabilityManager::DiscoverabilityManager() :
|
||||||
_mode("discoverabilityMode", DEFAULT_DISCOVERABILITY_MODE)
|
_mode("discoverabilityMode", DEFAULT_DISCOVERABILITY_MODE)
|
||||||
|
@ -29,53 +30,103 @@ DiscoverabilityManager::DiscoverabilityManager() :
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString API_USER_LOCATION_PATH = "/api/v1/user/location";
|
const QString API_USER_LOCATION_PATH = "/api/v1/user/location";
|
||||||
|
const QString API_USER_HEARTBEAT_PATH = "/api/v1/user/heartbeat";
|
||||||
|
|
||||||
|
const QString SESSION_ID_KEY = "session_id";
|
||||||
|
|
||||||
void DiscoverabilityManager::updateLocation() {
|
void DiscoverabilityManager::updateLocation() {
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
|
|
||||||
if (_mode.get() != Discoverability::None) {
|
if (_mode.get() != Discoverability::None && accountManager.isLoggedIn()) {
|
||||||
auto addressManager = DependencyManager::get<AddressManager>();
|
auto addressManager = DependencyManager::get<AddressManager>();
|
||||||
DomainHandler& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
|
DomainHandler& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
|
||||||
|
|
||||||
if (accountManager.isLoggedIn() && domainHandler.isConnected()
|
// construct a QJsonObject given the user's current address information
|
||||||
&& (!addressManager->getRootPlaceID().isNull() || !domainHandler.getUUID().isNull())) {
|
QJsonObject rootObject;
|
||||||
|
|
||||||
// construct a QJsonObject given the user's current address information
|
QJsonObject locationObject;
|
||||||
QJsonObject rootObject;
|
|
||||||
|
QString pathString = addressManager->currentPath();
|
||||||
QJsonObject locationObject;
|
|
||||||
|
const QString LOCATION_KEY_IN_ROOT = "location";
|
||||||
QString pathString = addressManager->currentPath();
|
|
||||||
|
const QString PATH_KEY_IN_LOCATION = "path";
|
||||||
const QString LOCATION_KEY_IN_ROOT = "location";
|
locationObject.insert(PATH_KEY_IN_LOCATION, pathString);
|
||||||
|
|
||||||
const QString PATH_KEY_IN_LOCATION = "path";
|
const QString CONNECTED_KEY_IN_LOCATION = "connected";
|
||||||
locationObject.insert(PATH_KEY_IN_LOCATION, pathString);
|
locationObject.insert(CONNECTED_KEY_IN_LOCATION, domainHandler.isConnected());
|
||||||
|
|
||||||
if (!addressManager->getRootPlaceID().isNull()) {
|
if (!addressManager->getRootPlaceID().isNull()) {
|
||||||
const QString PLACE_ID_KEY_IN_LOCATION = "place_id";
|
const QString PLACE_ID_KEY_IN_LOCATION = "place_id";
|
||||||
locationObject.insert(PLACE_ID_KEY_IN_LOCATION,
|
locationObject.insert(PLACE_ID_KEY_IN_LOCATION,
|
||||||
uuidStringWithoutCurlyBraces(addressManager->getRootPlaceID()));
|
uuidStringWithoutCurlyBraces(addressManager->getRootPlaceID()));
|
||||||
|
|
||||||
} else {
|
|
||||||
const QString DOMAIN_ID_KEY_IN_LOCATION = "domain_id";
|
|
||||||
locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION,
|
|
||||||
uuidStringWithoutCurlyBraces(domainHandler.getUUID()));
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString FRIENDS_ONLY_KEY_IN_LOCATION = "friends_only";
|
|
||||||
locationObject.insert(FRIENDS_ONLY_KEY_IN_LOCATION, (_mode.get() == Discoverability::Friends));
|
|
||||||
|
|
||||||
rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject);
|
|
||||||
|
|
||||||
accountManager.sendRequest(API_USER_LOCATION_PATH, AccountManagerAuth::Required,
|
|
||||||
QNetworkAccessManager::PutOperation,
|
|
||||||
JSONCallbackParameters(), QJsonDocument(rootObject).toJson());
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
if (!domainHandler.getUUID().isNull()) {
|
||||||
|
const QString DOMAIN_ID_KEY_IN_LOCATION = "domain_id";
|
||||||
|
locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION,
|
||||||
|
uuidStringWithoutCurlyBraces(domainHandler.getUUID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// in case the place/domain isn't in the database, we send the network address and port
|
||||||
|
auto& domainSockAddr = domainHandler.getSockAddr();
|
||||||
|
const QString NETWORK_ADRESS_KEY_IN_LOCATION = "network_address";
|
||||||
|
locationObject.insert(NETWORK_ADRESS_KEY_IN_LOCATION, domainSockAddr.getAddress().toString());
|
||||||
|
|
||||||
|
const QString NETWORK_ADDRESS_PORT_IN_LOCATION = "network_port";
|
||||||
|
locationObject.insert(NETWORK_ADDRESS_PORT_IN_LOCATION, domainSockAddr.getPort());
|
||||||
|
|
||||||
|
const QString FRIENDS_ONLY_KEY_IN_LOCATION = "friends_only";
|
||||||
|
locationObject.insert(FRIENDS_ONLY_KEY_IN_LOCATION, (_mode.get() == Discoverability::Friends));
|
||||||
|
|
||||||
|
// if we have a session ID add it now, otherwise add a null value
|
||||||
|
rootObject[SESSION_ID_KEY] = _sessionID.isEmpty() ? QJsonValue() : _sessionID;
|
||||||
|
|
||||||
|
JSONCallbackParameters callbackParameters;
|
||||||
|
callbackParameters.jsonCallbackReceiver = this;
|
||||||
|
callbackParameters.jsonCallbackMethod = "handleHeartbeatResponse";
|
||||||
|
|
||||||
|
// figure out if we'll send a fresh location or just a simple heartbeat
|
||||||
|
auto apiPath = API_USER_HEARTBEAT_PATH;
|
||||||
|
|
||||||
|
if (locationObject != _lastLocationObject) {
|
||||||
|
// we have a changed location, send it now
|
||||||
|
_lastLocationObject = locationObject;
|
||||||
|
|
||||||
|
rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject);
|
||||||
|
|
||||||
|
apiPath = API_USER_LOCATION_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
accountManager.sendRequest(apiPath, AccountManagerAuth::Required,
|
||||||
|
QNetworkAccessManager::PutOperation,
|
||||||
|
callbackParameters, QJsonDocument(rootObject).toJson());
|
||||||
|
|
||||||
|
} else if (UserActivityLogger::getInstance().isEnabled()) {
|
||||||
// we still send a heartbeat to the metaverse server for stats collection
|
// we still send a heartbeat to the metaverse server for stats collection
|
||||||
const QString API_USER_HEARTBEAT_PATH = "/api/v1/user/heartbeat";
|
|
||||||
accountManager.sendRequest(API_USER_HEARTBEAT_PATH, AccountManagerAuth::Required, QNetworkAccessManager::PutOperation);
|
JSONCallbackParameters callbackParameters;
|
||||||
|
callbackParameters.jsonCallbackReceiver = this;
|
||||||
|
callbackParameters.jsonCallbackMethod = "handleHeartbeatResponse";
|
||||||
|
|
||||||
|
QJsonObject heartbeatObject;
|
||||||
|
if (!_sessionID.isEmpty()) {
|
||||||
|
heartbeatObject[SESSION_ID_KEY] = _sessionID;
|
||||||
|
} else {
|
||||||
|
heartbeatObject[SESSION_ID_KEY] = QJsonValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
accountManager.sendRequest(API_USER_HEARTBEAT_PATH, AccountManagerAuth::Optional,
|
||||||
|
QNetworkAccessManager::PutOperation, callbackParameters,
|
||||||
|
QJsonDocument(heartbeatObject).toJson());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiscoverabilityManager::handleHeartbeatResponse(QNetworkReply& requestReply) {
|
||||||
|
auto dataObject = AccountManager::dataObjectFromResponse(requestReply);
|
||||||
|
|
||||||
|
if (!dataObject.isEmpty()) {
|
||||||
|
_sessionID = dataObject[SESSION_ID_KEY].toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +144,9 @@ void DiscoverabilityManager::setDiscoverabilityMode(Discoverability::Mode discov
|
||||||
if (static_cast<int>(_mode.get()) == Discoverability::None) {
|
if (static_cast<int>(_mode.get()) == Discoverability::None) {
|
||||||
// if we just got set to no discoverability, make sure that we delete our location in DB
|
// if we just got set to no discoverability, make sure that we delete our location in DB
|
||||||
removeLocation();
|
removeLocation();
|
||||||
|
} else {
|
||||||
|
// we have a discoverability mode that says we should send a location, do that right away
|
||||||
|
updateLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
emit discoverabilityModeChanged(discoverabilityMode);
|
emit discoverabilityModeChanged(discoverabilityMode);
|
||||||
|
|
|
@ -42,10 +42,15 @@ public slots:
|
||||||
signals:
|
signals:
|
||||||
void discoverabilityModeChanged(Discoverability::Mode discoverabilityMode);
|
void discoverabilityModeChanged(Discoverability::Mode discoverabilityMode);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleHeartbeatResponse(QNetworkReply& requestReply);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DiscoverabilityManager();
|
DiscoverabilityManager();
|
||||||
|
|
||||||
Setting::Handle<int> _mode;
|
Setting::Handle<int> _mode;
|
||||||
|
QString _sessionID;
|
||||||
|
QJsonObject _lastLocationObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_DiscoverabilityManager_h
|
#endif // hifi_DiscoverabilityManager_h
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
|
#include <OctreeUtils.h>
|
||||||
#include <Util.h>
|
#include <Util.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
@ -216,7 +217,7 @@ QString LODManager::getLODFeedbackText() {
|
||||||
bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
|
bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
|
||||||
// FIXME - eventually we want to use the render accuracy as an indicator for the level of detail
|
// FIXME - eventually we want to use the render accuracy as an indicator for the level of detail
|
||||||
// to use in rendering.
|
// to use in rendering.
|
||||||
float renderAccuracy = args->_viewFrustum->calculateRenderAccuracy(bounds, args->_sizeScale, args->_boundaryLevelAdjust);
|
float renderAccuracy = calculateRenderAccuracy(args->getViewFrustum().getPosition(), bounds, args->_sizeScale, args->_boundaryLevelAdjust);
|
||||||
return (renderAccuracy > 0.0f);
|
return (renderAccuracy > 0.0f);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -228,7 +229,6 @@ void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
|
||||||
_boundaryLevelAdjust = boundaryLevelAdjust;
|
_boundaryLevelAdjust = boundaryLevelAdjust;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LODManager::loadSettings() {
|
void LODManager::loadSettings() {
|
||||||
setDesktopLODDecreaseFPS(desktopLODDecreaseFPS.get());
|
setDesktopLODDecreaseFPS(desktopLODDecreaseFPS.get());
|
||||||
setHMDLODDecreaseFPS(hmdLODDecreaseFPS.get());
|
setHMDLODDecreaseFPS(hmdLODDecreaseFPS.get());
|
||||||
|
@ -239,4 +239,3 @@ void LODManager::saveSettings() {
|
||||||
hmdLODDecreaseFPS.set(getHMDLODDecreaseFPS());
|
hmdLODDecreaseFPS.set(getHMDLODDecreaseFPS());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -568,8 +568,6 @@ Menu::Menu() {
|
||||||
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::PipelineWarnings);
|
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::PipelineWarnings);
|
||||||
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::LogExtraTimings);
|
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::LogExtraTimings);
|
||||||
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::SuppressShortTimings);
|
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::SuppressShortTimings);
|
||||||
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::SupressDeadlockWatchdogStatus, 0, false,
|
|
||||||
qApp, SLOT(toggleSuppressDeadlockWatchdogStatus(bool)));
|
|
||||||
|
|
||||||
|
|
||||||
// Developer > Audio >>>
|
// Developer > Audio >>>
|
||||||
|
|
|
@ -170,6 +170,7 @@ namespace MenuOption {
|
||||||
const QString RunTimingTests = "Run Timing Tests";
|
const QString RunTimingTests = "Run Timing Tests";
|
||||||
const QString ScriptEditor = "Script Editor...";
|
const QString ScriptEditor = "Script Editor...";
|
||||||
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
|
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
|
||||||
|
const QString SetHomeLocation = "Set Home Location";
|
||||||
const QString ShowDSConnectTable = "Show Domain Connection Timing";
|
const QString ShowDSConnectTable = "Show Domain Connection Timing";
|
||||||
const QString ShowBordersEntityNodes = "Show Entity Nodes";
|
const QString ShowBordersEntityNodes = "Show Entity Nodes";
|
||||||
const QString ShowRealtimeEntityStats = "Show Realtime Entity Stats";
|
const QString ShowRealtimeEntityStats = "Show Realtime Entity Stats";
|
||||||
|
@ -181,7 +182,6 @@ namespace MenuOption {
|
||||||
const QString Stats = "Stats";
|
const QString Stats = "Stats";
|
||||||
const QString StopAllScripts = "Stop All Scripts";
|
const QString StopAllScripts = "Stop All Scripts";
|
||||||
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
||||||
const QString SupressDeadlockWatchdogStatus = "Supress Deadlock Watchdog Status";
|
|
||||||
const QString ThirdPerson = "Third Person";
|
const QString ThirdPerson = "Third Person";
|
||||||
const QString ThreePointCalibration = "3 Point Calibration";
|
const QString ThreePointCalibration = "3 Point Calibration";
|
||||||
const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus"; // FIXME - this value duplicated in Basic2DWindowOpenGLDisplayPlugin.cpp
|
const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus"; // FIXME - this value duplicated in Basic2DWindowOpenGLDisplayPlugin.cpp
|
||||||
|
|
|
@ -54,7 +54,7 @@ QOpenGLContext* PluginContainerProxy::getPrimaryContext() {
|
||||||
return qApp->_glWidget->context()->contextHandle();
|
return qApp->_glWidget->context()->contextHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
const DisplayPlugin* PluginContainerProxy::getActiveDisplayPlugin() const {
|
const DisplayPluginPointer PluginContainerProxy::getActiveDisplayPlugin() const {
|
||||||
return qApp->getActiveDisplayPlugin();
|
return qApp->getActiveDisplayPlugin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ class PluginContainerProxy : public QObject, PluginContainer {
|
||||||
virtual ui::Menu* getPrimaryMenu() override;
|
virtual ui::Menu* getPrimaryMenu() override;
|
||||||
virtual QOpenGLContext* getPrimaryContext() override;
|
virtual QOpenGLContext* getPrimaryContext() override;
|
||||||
virtual bool isForeground() override;
|
virtual bool isForeground() override;
|
||||||
virtual const DisplayPlugin* getActiveDisplayPlugin() const override;
|
virtual const DisplayPluginPointer getActiveDisplayPlugin() const override;
|
||||||
|
|
||||||
friend class Application;
|
friend class Application;
|
||||||
|
|
||||||
|
|
|
@ -194,8 +194,8 @@ void Stars::render(RenderArgs* renderArgs, float alpha) {
|
||||||
|
|
||||||
gpu::Batch& batch = *renderArgs->_batch;
|
gpu::Batch& batch = *renderArgs->_batch;
|
||||||
batch.setViewTransform(Transform());
|
batch.setViewTransform(Transform());
|
||||||
batch.setProjectionTransform(renderArgs->_viewFrustum->getProjection());
|
batch.setProjectionTransform(renderArgs->getViewFrustum().getProjection());
|
||||||
batch.setModelTransform(Transform().setRotation(glm::inverse(renderArgs->_viewFrustum->getOrientation()) *
|
batch.setModelTransform(Transform().setRotation(glm::inverse(renderArgs->getViewFrustum().getOrientation()) *
|
||||||
quat(vec3(TILT, 0, 0))));
|
quat(vec3(TILT, 0, 0))));
|
||||||
batch.setResourceTexture(0, textureCache->getWhiteTexture());
|
batch.setResourceTexture(0, textureCache->getWhiteTexture());
|
||||||
|
|
||||||
|
|
|
@ -131,71 +131,102 @@ const glm::vec3 randVector() {
|
||||||
// Do some basic timing tests and report the results
|
// Do some basic timing tests and report the results
|
||||||
void runTimingTests() {
|
void runTimingTests() {
|
||||||
// How long does it take to make a call to get the time?
|
// How long does it take to make a call to get the time?
|
||||||
|
const int numTimingTests = 3;
|
||||||
|
QElapsedTimer startTime;
|
||||||
|
float elapsedNSecs;
|
||||||
|
float elapsedUSecs;
|
||||||
|
|
||||||
|
qCDebug(interfaceapp, "numTimingTests: %d", numTimingTests);
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "QElapsedTimer::nsecElapsed() ns: %f", (double)elapsedNSecs / numTimingTests);
|
||||||
|
|
||||||
|
// Test sleep functions for accuracy
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numTimingTests; i++) {
|
||||||
|
QThread::msleep(1);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "QThread::msleep(1) ms: %f", (double)(elapsedNSecs / NSECS_PER_MSEC / numTimingTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numTimingTests; i++) {
|
||||||
|
QThread::sleep(1);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "QThread::sleep(1) s: %f", (double)(elapsedNSecs / NSECS_PER_MSEC / MSECS_PER_SECOND / numTimingTests));
|
||||||
|
|
||||||
|
const int numUsecTests = 1000;
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numUsecTests; i++) {
|
||||||
|
usleep(1);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(1) (1000x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numUsecTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numUsecTests; i++) {
|
||||||
|
usleep(10);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(10) (1000x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numUsecTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numUsecTests; i++) {
|
||||||
|
usleep(100);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(100) (1000x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numUsecTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numTimingTests; i++) {
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(1000) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numTimingTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numTimingTests; i++) {
|
||||||
|
usleep(1001);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(1001) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numTimingTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numTimingTests; i++) {
|
||||||
|
usleep(1500);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(1500) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numTimingTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
usleep(15000);
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(15000) (1x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC));
|
||||||
|
|
||||||
const int numTests = 1000000;
|
const int numTests = 1000000;
|
||||||
int* iResults = (int*)malloc(sizeof(int) * numTests);
|
int* iResults = (int*)malloc(sizeof(int) * numTests);
|
||||||
float fTest = 1.0;
|
float fTest = 1.0;
|
||||||
float* fResults = (float*)malloc(sizeof(float) * numTests);
|
float* fResults = (float*)malloc(sizeof(float) * numTests);
|
||||||
QElapsedTimer startTime;
|
|
||||||
startTime.start();
|
|
||||||
float elapsedUsecs;
|
|
||||||
|
|
||||||
float NSEC_TO_USEC = 1.0f / 1000.0f;
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "QElapsedTimer::nsecElapsed() usecs: %f", (double)elapsedUsecs);
|
|
||||||
|
|
||||||
// Test sleep functions for accuracy
|
|
||||||
startTime.start();
|
|
||||||
QThread::msleep(1);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "QThread::msleep(1) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
QThread::sleep(1);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "QThread::sleep(1) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
usleep(1);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "usleep(1) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
usleep(10);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "usleep(10) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
usleep(100);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "usleep(100) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
usleep(1000);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "usleep(1000) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
usleep(15000);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "usleep(15000) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
// Random number generation
|
// Random number generation
|
||||||
startTime.start();
|
startTime.start();
|
||||||
for (int i = 0; i < numTests; i++) {
|
for (int i = 0; i < numTests; i++) {
|
||||||
iResults[i] = rand();
|
iResults[i] = rand();
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp, "rand() stored in array usecs: %f, first result:%d",
|
qCDebug(interfaceapp, "rand() stored in array usecs: %f, first result:%d",
|
||||||
(double)(elapsedUsecs / numTests), iResults[0]);
|
(double)(elapsedUSecs / numTests), iResults[0]);
|
||||||
|
|
||||||
// Random number generation using randFloat()
|
// Random number generation using randFloat()
|
||||||
startTime.start();
|
startTime.start();
|
||||||
for (int i = 0; i < numTests; i++) {
|
for (int i = 0; i < numTests; i++) {
|
||||||
fResults[i] = randFloat();
|
fResults[i] = randFloat();
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp, "randFloat() stored in array usecs: %f, first result: %f",
|
qCDebug(interfaceapp, "randFloat() stored in array usecs: %f, first result: %f",
|
||||||
(double)(elapsedUsecs / numTests), (double)(fResults[0]));
|
(double)(elapsedUSecs / numTests), (double)(fResults[0]));
|
||||||
|
|
||||||
free(iResults);
|
free(iResults);
|
||||||
free(fResults);
|
free(fResults);
|
||||||
|
@ -206,8 +237,8 @@ void runTimingTests() {
|
||||||
for (int i = 0; i < numTests; i++) {
|
for (int i = 0; i < numTests; i++) {
|
||||||
fTest = powf(fTest, 0.5f);
|
fTest = powf(fTest, 0.5f);
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp, "powf(f, 0.5) usecs: %f", (double)(elapsedUsecs / (float) numTests));
|
qCDebug(interfaceapp, "powf(f, 0.5) usecs: %f", (double)(elapsedUSecs / (float) numTests));
|
||||||
|
|
||||||
// Vector Math
|
// Vector Math
|
||||||
float distance;
|
float distance;
|
||||||
|
@ -218,9 +249,9 @@ void runTimingTests() {
|
||||||
//float distanceSquared = glm::dot(temp, temp);
|
//float distanceSquared = glm::dot(temp, temp);
|
||||||
distance = glm::distance(pointA, pointB);
|
distance = glm::distance(pointA, pointB);
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp, "vector math usecs: %f [%f usecs total for %d tests], last result:%f",
|
qCDebug(interfaceapp, "vector math usecs: %f [%f usecs total for %d tests], last result:%f",
|
||||||
(double)(elapsedUsecs / (float) numTests), (double)elapsedUsecs, numTests, (double)distance);
|
(double)(elapsedUSecs / (float) numTests), (double)elapsedUSecs, numTests, (double)distance);
|
||||||
|
|
||||||
// Vec3 test
|
// Vec3 test
|
||||||
glm::vec3 vecA(randVector()), vecB(randVector());
|
glm::vec3 vecA(randVector()), vecB(randVector());
|
||||||
|
@ -231,9 +262,9 @@ void runTimingTests() {
|
||||||
glm::vec3 temp = vecA-vecB;
|
glm::vec3 temp = vecA-vecB;
|
||||||
result = glm::dot(temp,temp);
|
result = glm::dot(temp,temp);
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp, "vec3 assign and dot() usecs: %f, last result:%f",
|
qCDebug(interfaceapp, "vec3 assign and dot() usecs: %f, last result:%f",
|
||||||
(double)(elapsedUsecs / numTests), (double)result);
|
(double)(elapsedUSecs / numTests), (double)result);
|
||||||
|
|
||||||
|
|
||||||
quint64 BYTE_CODE_MAX_TEST_VALUE = 99999999;
|
quint64 BYTE_CODE_MAX_TEST_VALUE = 99999999;
|
||||||
|
@ -265,9 +296,9 @@ void runTimingTests() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp) << "ByteCountCoded<quint64> usecs: " << elapsedUsecs
|
qCDebug(interfaceapp) << "ByteCountCoded<quint64> usecs: " << elapsedUSecs
|
||||||
<< "per test:" << (double) (elapsedUsecs / tests)
|
<< "per test:" << (double) (elapsedUSecs / tests)
|
||||||
<< "tests:" << tests
|
<< "tests:" << tests
|
||||||
<< "failed:" << failed;
|
<< "failed:" << failed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <LODManager.h>
|
#include <LODManager.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
|
#include <OctreeUtils.h>
|
||||||
#include <udt/PacketHeaders.h>
|
#include <udt/PacketHeaders.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
@ -171,7 +172,10 @@ void Avatar::simulate(float deltaTime) {
|
||||||
// update the shouldAnimate flag to match whether or not we will render the avatar.
|
// update the shouldAnimate flag to match whether or not we will render the avatar.
|
||||||
const float MINIMUM_VISIBILITY_FOR_ON = 0.4f;
|
const float MINIMUM_VISIBILITY_FOR_ON = 0.4f;
|
||||||
const float MAXIMUM_VISIBILITY_FOR_OFF = 0.6f;
|
const float MAXIMUM_VISIBILITY_FOR_OFF = 0.6f;
|
||||||
float visibility = qApp->getViewFrustum()->calculateRenderAccuracy(getBounds(), DependencyManager::get<LODManager>()->getOctreeSizeScale());
|
ViewFrustum viewFrustum;
|
||||||
|
qApp->copyViewFrustum(viewFrustum);
|
||||||
|
float visibility = calculateRenderAccuracy(viewFrustum.getPosition(),
|
||||||
|
getBounds(), DependencyManager::get<LODManager>()->getOctreeSizeScale());
|
||||||
if (!_shouldAnimate) {
|
if (!_shouldAnimate) {
|
||||||
if (visibility > MINIMUM_VISIBILITY_FOR_ON) {
|
if (visibility > MINIMUM_VISIBILITY_FOR_ON) {
|
||||||
_shouldAnimate = true;
|
_shouldAnimate = true;
|
||||||
|
@ -184,8 +188,9 @@ void Avatar::simulate(float deltaTime) {
|
||||||
|
|
||||||
// simple frustum check
|
// simple frustum check
|
||||||
float boundingRadius = getBoundingRadius();
|
float boundingRadius = getBoundingRadius();
|
||||||
bool avatarPositionInView = qApp->getDisplayViewFrustum()->sphereIntersectsFrustum(getPosition(), boundingRadius);
|
qApp->copyDisplayViewFrustum(viewFrustum);
|
||||||
bool avatarMeshInView = qApp->getDisplayViewFrustum()->boxIntersectsFrustum(_skeletonModel->getRenderableMeshBound());
|
bool avatarPositionInView = viewFrustum.sphereIntersectsFrustum(getPosition(), boundingRadius);
|
||||||
|
bool avatarMeshInView = viewFrustum.boxIntersectsFrustum(_skeletonModel->getRenderableMeshBound());
|
||||||
|
|
||||||
if (_shouldAnimate && !_shouldSkipRender && (avatarPositionInView || avatarMeshInView)) {
|
if (_shouldAnimate && !_shouldSkipRender && (avatarPositionInView || avatarMeshInView)) {
|
||||||
{
|
{
|
||||||
|
@ -381,17 +386,16 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// simple frustum check
|
{ // simple frustum check
|
||||||
float boundingRadius = getBoundingRadius();
|
ViewFrustum frustum;
|
||||||
ViewFrustum* frustum = nullptr;
|
if (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) {
|
||||||
if (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) {
|
qApp->copyShadowViewFrustum(frustum);
|
||||||
frustum = qApp->getShadowViewFrustum();
|
} else {
|
||||||
} else {
|
qApp->copyDisplayViewFrustum(frustum);
|
||||||
frustum = qApp->getDisplayViewFrustum();
|
}
|
||||||
}
|
if (!frustum.sphereIntersectsFrustum(getPosition(), getBoundingRadius())) {
|
||||||
|
return;
|
||||||
if (!frustum->sphereIntersectsFrustum(getPosition(), boundingRadius)) {
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 toTarget = cameraPosition - getPosition();
|
glm::vec3 toTarget = cameraPosition - getPosition();
|
||||||
|
@ -413,7 +417,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
||||||
: GLOW_FROM_AVERAGE_LOUDNESS;
|
: GLOW_FROM_AVERAGE_LOUDNESS;
|
||||||
|
|
||||||
// render body
|
// render body
|
||||||
renderBody(renderArgs, frustum, glowLevel);
|
renderBody(renderArgs, glowLevel);
|
||||||
|
|
||||||
if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE) {
|
if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||||
// add local lights
|
// add local lights
|
||||||
|
@ -502,9 +506,8 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
||||||
|
|
||||||
auto cameraMode = qApp->getCamera()->getMode();
|
auto cameraMode = qApp->getCamera()->getMode();
|
||||||
if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) {
|
if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) {
|
||||||
auto& frustum = *renderArgs->_viewFrustum;
|
auto& frustum = renderArgs->getViewFrustum();
|
||||||
auto textPosition = getDisplayNamePosition();
|
auto textPosition = getDisplayNamePosition();
|
||||||
|
|
||||||
if (frustum.pointIntersectsFrustum(textPosition)) {
|
if (frustum.pointIntersectsFrustum(textPosition)) {
|
||||||
renderDisplayName(batch, frustum, textPosition);
|
renderDisplayName(batch, frustum, textPosition);
|
||||||
}
|
}
|
||||||
|
@ -553,7 +556,7 @@ void Avatar::fixupModelsInScene() {
|
||||||
scene->enqueuePendingChanges(pendingChanges);
|
scene->enqueuePendingChanges(pendingChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel) {
|
void Avatar::renderBody(RenderArgs* renderArgs, float glowLevel) {
|
||||||
fixupModelsInScene();
|
fixupModelsInScene();
|
||||||
getHead()->renderLookAts(renderArgs);
|
getHead()->renderLookAts(renderArgs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,7 +232,7 @@ protected:
|
||||||
|
|
||||||
Transform calculateDisplayNameTransform(const ViewFrustum& view, const glm::vec3& textPosition) const;
|
Transform calculateDisplayNameTransform(const ViewFrustum& view, const glm::vec3& textPosition) const;
|
||||||
void renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const glm::vec3& textPosition) const;
|
void renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const glm::vec3& textPosition) const;
|
||||||
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f);
|
virtual void renderBody(RenderArgs* renderArgs, float glowLevel = 0.0f);
|
||||||
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const;
|
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const;
|
||||||
virtual void fixupModelsInScene();
|
virtual void fixupModelsInScene();
|
||||||
|
|
||||||
|
|
|
@ -93,13 +93,13 @@ void AvatarActionHold::prepareForPhysicsSimulation() {
|
||||||
activateBody(true);
|
activateBody(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Avatar> AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity) {
|
glm::vec3& linearVelocity, glm::vec3& angularVelocity) {
|
||||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||||
auto holdingAvatar = std::static_pointer_cast<Avatar>(avatarManager->getAvatarBySessionID(_holderID));
|
auto holdingAvatar = std::static_pointer_cast<Avatar>(avatarManager->getAvatarBySessionID(_holderID));
|
||||||
|
|
||||||
if (!holdingAvatar) {
|
if (!holdingAvatar) {
|
||||||
return holdingAvatar;
|
return false;;
|
||||||
}
|
}
|
||||||
|
|
||||||
withReadLock([&]{
|
withReadLock([&]{
|
||||||
|
@ -171,62 +171,17 @@ std::shared_ptr<Avatar> AvatarActionHold::getTarget(float deltaTimeStep, glm::qu
|
||||||
linearVelocity = linearVelocity + glm::cross(angularVelocity, position - palmPosition);
|
linearVelocity = linearVelocity + glm::cross(angularVelocity, position - palmPosition);
|
||||||
});
|
});
|
||||||
|
|
||||||
return holdingAvatar;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
|
void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
|
||||||
glm::quat rotation;
|
if (_kinematic) {
|
||||||
glm::vec3 position;
|
if (prepareForSpringUpdate(deltaTimeStep)) {
|
||||||
glm::vec3 linearVelocity;
|
|
||||||
glm::vec3 angularVelocity;
|
|
||||||
bool valid = false;
|
|
||||||
int holdCount = 0;
|
|
||||||
|
|
||||||
auto ownerEntity = _ownerEntity.lock();
|
|
||||||
if (!ownerEntity) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QList<EntityActionPointer> holdActions = ownerEntity->getActionsOfType(ACTION_TYPE_HOLD);
|
|
||||||
foreach (EntityActionPointer action, holdActions) {
|
|
||||||
std::shared_ptr<AvatarActionHold> holdAction = std::static_pointer_cast<AvatarActionHold>(action);
|
|
||||||
glm::quat rotationForAction;
|
|
||||||
glm::vec3 positionForAction;
|
|
||||||
glm::vec3 linearVelocityForAction, angularVelocityForAction;
|
|
||||||
std::shared_ptr<Avatar> holdingAvatar = holdAction->getTarget(deltaTimeStep, rotationForAction, positionForAction, linearVelocityForAction, angularVelocityForAction);
|
|
||||||
if (holdingAvatar) {
|
|
||||||
holdCount ++;
|
|
||||||
if (holdAction.get() == this) {
|
|
||||||
// only use the rotation for this action
|
|
||||||
valid = true;
|
|
||||||
rotation = rotationForAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
position += positionForAction;
|
|
||||||
linearVelocity += linearVelocityForAction;
|
|
||||||
angularVelocity += angularVelocityForAction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid && holdCount > 0) {
|
|
||||||
position /= holdCount;
|
|
||||||
linearVelocity /= holdCount;
|
|
||||||
angularVelocity /= holdCount;
|
|
||||||
|
|
||||||
withWriteLock([&]{
|
|
||||||
_positionalTarget = position;
|
|
||||||
_rotationalTarget = rotation;
|
|
||||||
_linearVelocityTarget = linearVelocity;
|
|
||||||
_angularVelocityTarget = angularVelocity;
|
|
||||||
_positionalTargetSet = true;
|
|
||||||
_rotationalTargetSet = true;
|
|
||||||
_active = true;
|
|
||||||
});
|
|
||||||
if (_kinematic) {
|
|
||||||
doKinematicUpdate(deltaTimeStep);
|
doKinematicUpdate(deltaTimeStep);
|
||||||
} else {
|
|
||||||
forceBodyNonStatic();
|
|
||||||
ObjectActionSpring::updateActionWorker(deltaTimeStep);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
forceBodyNonStatic();
|
||||||
|
ObjectActionSpring::updateActionWorker(deltaTimeStep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,8 @@ public:
|
||||||
virtual bool shouldSuppressLocationEdits() override { return _active && !_ownerEntity.expired(); }
|
virtual bool shouldSuppressLocationEdits() override { return _active && !_ownerEntity.expired(); }
|
||||||
|
|
||||||
bool getAvatarRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
|
bool getAvatarRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
|
||||||
std::shared_ptr<Avatar> getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
virtual bool getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity);
|
glm::vec3& linearVelocity, glm::vec3& angularVelocity) override;
|
||||||
|
|
||||||
virtual void prepareForPhysicsSimulation() override;
|
virtual void prepareForPhysicsSimulation() override;
|
||||||
|
|
||||||
|
@ -51,9 +51,6 @@ private:
|
||||||
QString _hand { "right" };
|
QString _hand { "right" };
|
||||||
QUuid _holderID;
|
QUuid _holderID;
|
||||||
|
|
||||||
glm::vec3 _linearVelocityTarget;
|
|
||||||
glm::vec3 _angularVelocityTarget;
|
|
||||||
|
|
||||||
bool _kinematic { false };
|
bool _kinematic { false };
|
||||||
bool _kinematicSetVelocity { false };
|
bool _kinematicSetVelocity { false };
|
||||||
bool _previousSet { false };
|
bool _previousSet { false };
|
||||||
|
|
|
@ -309,9 +309,11 @@ void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents
|
||||||
// my avatar. (Other user machines will make a similar analysis and inject sound for their collisions.)
|
// my avatar. (Other user machines will make a similar analysis and inject sound for their collisions.)
|
||||||
if (collision.idA.isNull() || collision.idB.isNull()) {
|
if (collision.idA.isNull() || collision.idB.isNull()) {
|
||||||
MyAvatar* myAvatar = getMyAvatar();
|
MyAvatar* myAvatar = getMyAvatar();
|
||||||
const QString& collisionSoundURL = myAvatar->getCollisionSoundURL();
|
auto collisionSound = myAvatar->getCollisionSound();
|
||||||
if (!collisionSoundURL.isEmpty()) {
|
if (collisionSound) {
|
||||||
const float velocityChange = glm::length(collision.velocityChange);
|
const auto characterController = myAvatar->getCharacterController();
|
||||||
|
const float avatarVelocityChange = (characterController ? glm::length(characterController->getVelocityChange()) : 0.0f);
|
||||||
|
const float velocityChange = glm::length(collision.velocityChange) + avatarVelocityChange;
|
||||||
const float MIN_AVATAR_COLLISION_ACCELERATION = 0.01f;
|
const float MIN_AVATAR_COLLISION_ACCELERATION = 0.01f;
|
||||||
const bool isSound = (collision.type == CONTACT_EVENT_TYPE_START) && (velocityChange > MIN_AVATAR_COLLISION_ACCELERATION);
|
const bool isSound = (collision.type == CONTACT_EVENT_TYPE_START) && (velocityChange > MIN_AVATAR_COLLISION_ACCELERATION);
|
||||||
|
|
||||||
|
@ -327,7 +329,7 @@ void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents
|
||||||
// but most avatars are roughly the same size, so let's not be so fancy yet.
|
// but most avatars are roughly the same size, so let's not be so fancy yet.
|
||||||
const float AVATAR_STRETCH_FACTOR = 1.0f;
|
const float AVATAR_STRETCH_FACTOR = 1.0f;
|
||||||
|
|
||||||
AudioInjector::playSound(collisionSoundURL, energyFactorOfFull, AVATAR_STRETCH_FACTOR, myAvatar->getPosition());
|
AudioInjector::playSound(collisionSound, energyFactorOfFull, AVATAR_STRETCH_FACTOR, myAvatar->getPosition());
|
||||||
myAvatar->collisionWithEntity(collision);
|
myAvatar->collisionWithEntity(collision);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,11 +78,11 @@ private:
|
||||||
void simulateAvatarFades(float deltaTime);
|
void simulateAvatarFades(float deltaTime);
|
||||||
|
|
||||||
// virtual overrides
|
// virtual overrides
|
||||||
virtual AvatarSharedPointer newSharedAvatar();
|
virtual AvatarSharedPointer newSharedAvatar() override;
|
||||||
virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
|
virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) override;
|
||||||
|
|
||||||
virtual void removeAvatar(const QUuid& sessionUUID);
|
virtual void removeAvatar(const QUuid& sessionUUID) override;
|
||||||
virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar);
|
virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar) override;
|
||||||
|
|
||||||
QVector<AvatarSharedPointer> _avatarFades;
|
QVector<AvatarSharedPointer> _avatarFades;
|
||||||
std::shared_ptr<MyAvatar> _myAvatar;
|
std::shared_ptr<MyAvatar> _myAvatar;
|
||||||
|
|
|
@ -316,9 +316,6 @@ void Head::relaxLean(float deltaTime) {
|
||||||
_deltaLeanForward *= relaxationFactor;
|
_deltaLeanForward *= relaxationFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Head::renderLookAts(RenderArgs* renderArgs) {
|
void Head::renderLookAts(RenderArgs* renderArgs) {
|
||||||
renderLookAts(renderArgs, _leftEyePosition, _rightEyePosition);
|
renderLookAts(renderArgs, _leftEyePosition, _rightEyePosition);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,10 @@ class Avatar;
|
||||||
class Head : public HeadData {
|
class Head : public HeadData {
|
||||||
public:
|
public:
|
||||||
explicit Head(Avatar* owningAvatar);
|
explicit Head(Avatar* owningAvatar);
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void reset();
|
void reset();
|
||||||
void simulate(float deltaTime, bool isMine, bool billboard = false);
|
void simulate(float deltaTime, bool isMine, bool billboard = false);
|
||||||
void render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum);
|
|
||||||
void setScale(float scale);
|
void setScale(float scale);
|
||||||
void setPosition(glm::vec3 position) { _position = position; }
|
void setPosition(glm::vec3 position) { _position = position; }
|
||||||
void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; }
|
void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; }
|
||||||
|
@ -44,7 +43,7 @@ public:
|
||||||
|
|
||||||
/// \return orientationBase+Delta
|
/// \return orientationBase+Delta
|
||||||
glm::quat getFinalOrientationInLocalFrame() const;
|
glm::quat getFinalOrientationInLocalFrame() const;
|
||||||
|
|
||||||
/// \return orientationBody * (orientationBase+Delta)
|
/// \return orientationBody * (orientationBase+Delta)
|
||||||
glm::quat getFinalOrientationInWorldFrame() const;
|
glm::quat getFinalOrientationInWorldFrame() const;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include <AccountManager.h>
|
#include <AccountManager.h>
|
||||||
#include <AddressManager.h>
|
#include <AddressManager.h>
|
||||||
#include <AudioClient.h>
|
#include <AudioClient.h>
|
||||||
#include <DependencyManager.h>
|
|
||||||
#include <display-plugins/DisplayPlugin.h>
|
#include <display-plugins/DisplayPlugin.h>
|
||||||
#include <FSTReader.h>
|
#include <FSTReader.h>
|
||||||
#include <GeometryUtil.h>
|
#include <GeometryUtil.h>
|
||||||
|
@ -32,6 +31,7 @@
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
#include <SoundCache.h>
|
||||||
#include <TextRenderer3D.h>
|
#include <TextRenderer3D.h>
|
||||||
#include <UserActivityLogger.h>
|
#include <UserActivityLogger.h>
|
||||||
#include <AnimDebugDraw.h>
|
#include <AnimDebugDraw.h>
|
||||||
|
@ -97,7 +97,6 @@ MyAvatar::MyAvatar(RigPointer rig) :
|
||||||
_scriptedMotorTimescale(DEFAULT_SCRIPTED_MOTOR_TIMESCALE),
|
_scriptedMotorTimescale(DEFAULT_SCRIPTED_MOTOR_TIMESCALE),
|
||||||
_scriptedMotorFrame(SCRIPTED_MOTOR_CAMERA_FRAME),
|
_scriptedMotorFrame(SCRIPTED_MOTOR_CAMERA_FRAME),
|
||||||
_motionBehaviors(AVATAR_MOTION_DEFAULTS),
|
_motionBehaviors(AVATAR_MOTION_DEFAULTS),
|
||||||
_collisionSoundURL(""),
|
|
||||||
_characterController(this),
|
_characterController(this),
|
||||||
_lookAtTargetAvatar(),
|
_lookAtTargetAvatar(),
|
||||||
_shouldRender(true),
|
_shouldRender(true),
|
||||||
|
@ -546,7 +545,9 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
||||||
head->setDeltaYaw(estimatedRotation.y);
|
head->setDeltaYaw(estimatedRotation.y);
|
||||||
head->setDeltaRoll(estimatedRotation.z);
|
head->setDeltaRoll(estimatedRotation.z);
|
||||||
} else {
|
} else {
|
||||||
float magnifyFieldOfView = qApp->getViewFrustum()->getFieldOfView() / _realWorldFieldOfView.get();
|
ViewFrustum viewFrustum;
|
||||||
|
qApp->copyViewFrustum(viewFrustum);
|
||||||
|
float magnifyFieldOfView = viewFrustum.getFieldOfView() / _realWorldFieldOfView.get();
|
||||||
head->setDeltaPitch(estimatedRotation.x * magnifyFieldOfView);
|
head->setDeltaPitch(estimatedRotation.x * magnifyFieldOfView);
|
||||||
head->setDeltaYaw(estimatedRotation.y * magnifyFieldOfView);
|
head->setDeltaYaw(estimatedRotation.y * magnifyFieldOfView);
|
||||||
head->setDeltaRoll(estimatedRotation.z);
|
head->setDeltaRoll(estimatedRotation.z);
|
||||||
|
@ -663,14 +664,6 @@ void MyAvatar::restoreRoleAnimation(const QString& role) {
|
||||||
_rig->restoreRoleAnimation(role);
|
_rig->restoreRoleAnimation(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::prefetchAnimation(const QString& url) {
|
|
||||||
if (QThread::currentThread() != thread()) {
|
|
||||||
QMetaObject::invokeMethod(this, "prefetchAnimation", Q_ARG(const QString&, url));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_rig->prefetchAnimation(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyAvatar::saveData() {
|
void MyAvatar::saveData() {
|
||||||
Settings settings;
|
Settings settings;
|
||||||
settings.beginGroup("Avatar");
|
settings.beginGroup("Avatar");
|
||||||
|
@ -916,7 +909,8 @@ void MyAvatar::updateLookAtTargetAvatar() {
|
||||||
avatar->setIsLookAtTarget(false);
|
avatar->setIsLookAtTarget(false);
|
||||||
if (!avatar->isMyAvatar() && avatar->isInitialized() &&
|
if (!avatar->isMyAvatar() && avatar->isInitialized() &&
|
||||||
(distanceTo < GREATEST_LOOKING_AT_DISTANCE * getUniformScale())) {
|
(distanceTo < GREATEST_LOOKING_AT_DISTANCE * getUniformScale())) {
|
||||||
float angleTo = glm::angle(lookForward, glm::normalize(avatar->getHead()->getEyePosition() - getHead()->getEyePosition()));
|
float radius = glm::length(avatar->getHead()->getEyePosition() - avatar->getHead()->getRightEyePosition());
|
||||||
|
float angleTo = coneSphereAngle(getHead()->getEyePosition(), lookForward, avatar->getHead()->getEyePosition(), radius);
|
||||||
if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) {
|
if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) {
|
||||||
_lookAtTargetAvatar = avatarPointer;
|
_lookAtTargetAvatar = avatarPointer;
|
||||||
_targetAvatarPosition = avatarPointer->getPosition();
|
_targetAvatarPosition = avatarPointer->getPosition();
|
||||||
|
@ -936,15 +930,17 @@ void MyAvatar::updateLookAtTargetAvatar() {
|
||||||
// (We will be adding that offset to the camera position, after making some other adjustments.)
|
// (We will be adding that offset to the camera position, after making some other adjustments.)
|
||||||
glm::vec3 gazeOffset = lookAtPosition - getHead()->getEyePosition();
|
glm::vec3 gazeOffset = lookAtPosition - getHead()->getEyePosition();
|
||||||
|
|
||||||
|
ViewFrustum viewFrustum;
|
||||||
|
qApp->copyViewFrustum(viewFrustum);
|
||||||
|
|
||||||
// scale gazeOffset by IPD, if wearing an HMD.
|
// scale gazeOffset by IPD, if wearing an HMD.
|
||||||
if (qApp->isHMDMode()) {
|
if (qApp->isHMDMode()) {
|
||||||
glm::mat4 leftEye = qApp->getEyeOffset(Eye::Left);
|
glm::mat4 leftEye = qApp->getEyeOffset(Eye::Left);
|
||||||
glm::mat4 rightEye = qApp->getEyeOffset(Eye::Right);
|
glm::mat4 rightEye = qApp->getEyeOffset(Eye::Right);
|
||||||
glm::vec3 leftEyeHeadLocal = glm::vec3(leftEye[3]);
|
glm::vec3 leftEyeHeadLocal = glm::vec3(leftEye[3]);
|
||||||
glm::vec3 rightEyeHeadLocal = glm::vec3(rightEye[3]);
|
glm::vec3 rightEyeHeadLocal = glm::vec3(rightEye[3]);
|
||||||
auto humanSystem = qApp->getViewFrustum();
|
glm::vec3 humanLeftEye = viewFrustum.getPosition() + (viewFrustum.getOrientation() * leftEyeHeadLocal);
|
||||||
glm::vec3 humanLeftEye = humanSystem->getPosition() + (humanSystem->getOrientation() * leftEyeHeadLocal);
|
glm::vec3 humanRightEye = viewFrustum.getPosition() + (viewFrustum.getOrientation() * rightEyeHeadLocal);
|
||||||
glm::vec3 humanRightEye = humanSystem->getPosition() + (humanSystem->getOrientation() * rightEyeHeadLocal);
|
|
||||||
|
|
||||||
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
||||||
float ipdScale = hmdInterface->getIPDScale();
|
float ipdScale = hmdInterface->getIPDScale();
|
||||||
|
@ -958,7 +954,7 @@ void MyAvatar::updateLookAtTargetAvatar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// And now we can finally add that offset to the camera.
|
// And now we can finally add that offset to the camera.
|
||||||
glm::vec3 corrected = qApp->getViewFrustum()->getPosition() + gazeOffset;
|
glm::vec3 corrected = viewFrustum.getPosition() + gazeOffset;
|
||||||
|
|
||||||
avatar->getHead()->setCorrectedLookAtPosition(corrected);
|
avatar->getHead()->setCorrectedLookAtPosition(corrected);
|
||||||
|
|
||||||
|
@ -1239,12 +1235,20 @@ void MyAvatar::clearScriptableSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::setCollisionSoundURL(const QString& url) {
|
void MyAvatar::setCollisionSoundURL(const QString& url) {
|
||||||
_collisionSoundURL = url;
|
if (url != _collisionSoundURL) {
|
||||||
if (!url.isEmpty() && (url != _collisionSoundURL)) {
|
_collisionSoundURL = url;
|
||||||
emit newCollisionSoundURL(QUrl(url));
|
|
||||||
|
emit newCollisionSoundURL(QUrl(_collisionSoundURL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedSoundPointer MyAvatar::getCollisionSound() {
|
||||||
|
if (!_collisionSound) {
|
||||||
|
_collisionSound = DependencyManager::get<SoundCache>()->getSound(_collisionSoundURL);
|
||||||
|
}
|
||||||
|
return _collisionSound;
|
||||||
|
}
|
||||||
|
|
||||||
void MyAvatar::attach(const QString& modelURL, const QString& jointName,
|
void MyAvatar::attach(const QString& modelURL, const QString& jointName,
|
||||||
const glm::vec3& translation, const glm::quat& rotation,
|
const glm::vec3& translation, const glm::quat& rotation,
|
||||||
float scale, bool isSoft,
|
float scale, bool isSoft,
|
||||||
|
@ -1266,7 +1270,7 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName,
|
||||||
Avatar::attach(modelURL, jointName, translation, rotation, scale, isSoft, allowDuplicates, useSaved);
|
Avatar::attach(modelURL, jointName, translation, rotation, scale, isSoft, allowDuplicates, useSaved);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel) {
|
void MyAvatar::renderBody(RenderArgs* renderArgs, float glowLevel) {
|
||||||
|
|
||||||
if (!_skeletonModel->isRenderable()) {
|
if (!_skeletonModel->isRenderable()) {
|
||||||
return; // wait until all models are loaded
|
return; // wait until all models are loaded
|
||||||
|
@ -1274,11 +1278,6 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, fl
|
||||||
|
|
||||||
fixupModelsInScene();
|
fixupModelsInScene();
|
||||||
|
|
||||||
// Render head so long as the camera isn't inside it
|
|
||||||
if (shouldRenderHead(renderArgs)) {
|
|
||||||
getHead()->render(renderArgs, 1.0f, renderFrustum);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is drawing the lookat vectors from our avatar to wherever we're looking.
|
// This is drawing the lookat vectors from our avatar to wherever we're looking.
|
||||||
if (qApp->isHMDMode()) {
|
if (qApp->isHMDMode()) {
|
||||||
glm::vec3 cameraPosition = qApp->getCamera()->getPosition();
|
glm::vec3 cameraPosition = qApp->getCamera()->getPosition();
|
||||||
|
@ -1359,7 +1358,6 @@ void MyAvatar::destroyAnimGraph() {
|
||||||
void MyAvatar::preRender(RenderArgs* renderArgs) {
|
void MyAvatar::preRender(RenderArgs* renderArgs) {
|
||||||
|
|
||||||
render::ScenePointer scene = qApp->getMain3DScene();
|
render::ScenePointer scene = qApp->getMain3DScene();
|
||||||
const bool shouldDrawHead = shouldRenderHead(renderArgs);
|
|
||||||
|
|
||||||
if (_skeletonModel->initWhenReady(scene)) {
|
if (_skeletonModel->initWhenReady(scene)) {
|
||||||
initHeadBones();
|
initHeadBones();
|
||||||
|
@ -1411,6 +1409,7 @@ void MyAvatar::preRender(RenderArgs* renderArgs) {
|
||||||
DebugDraw::getInstance().updateMyAvatarPos(getPosition());
|
DebugDraw::getInstance().updateMyAvatarPos(getPosition());
|
||||||
DebugDraw::getInstance().updateMyAvatarRot(getOrientation());
|
DebugDraw::getInstance().updateMyAvatarRot(getOrientation());
|
||||||
|
|
||||||
|
const bool shouldDrawHead = shouldRenderHead(renderArgs);
|
||||||
if (shouldDrawHead != _prevShouldDrawHead) {
|
if (shouldDrawHead != _prevShouldDrawHead) {
|
||||||
_skeletonModel->setCauterizeBones(!shouldDrawHead);
|
_skeletonModel->setCauterizeBones(!shouldDrawHead);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
#include <Rig.h>
|
#include <Rig.h>
|
||||||
|
#include <Sound.h>
|
||||||
|
|
||||||
#include <controllers/Pose.h>
|
#include <controllers/Pose.h>
|
||||||
|
|
||||||
|
@ -143,9 +144,6 @@ public:
|
||||||
// remove an animation role override and return to the standard animation.
|
// remove an animation role override and return to the standard animation.
|
||||||
Q_INVOKABLE void restoreRoleAnimation(const QString& role);
|
Q_INVOKABLE void restoreRoleAnimation(const QString& role);
|
||||||
|
|
||||||
// prefetch animation
|
|
||||||
Q_INVOKABLE void prefetchAnimation(const QString& url);
|
|
||||||
|
|
||||||
// Adds handler(animStateDictionaryIn) => animStateDictionaryOut, which will be invoked just before each animGraph state update.
|
// Adds handler(animStateDictionaryIn) => animStateDictionaryOut, which will be invoked just before each animGraph state update.
|
||||||
// The handler will be called with an animStateDictionaryIn that has all those properties specified by the (possibly empty)
|
// The handler will be called with an animStateDictionaryIn that has all those properties specified by the (possibly empty)
|
||||||
// propertiesList argument. However for debugging, if the properties argument is null, all internal animGraph state is provided.
|
// propertiesList argument. However for debugging, if the properties argument is null, all internal animGraph state is provided.
|
||||||
|
@ -225,6 +223,9 @@ public:
|
||||||
const QString& getCollisionSoundURL() { return _collisionSoundURL; }
|
const QString& getCollisionSoundURL() { return _collisionSoundURL; }
|
||||||
void setCollisionSoundURL(const QString& url);
|
void setCollisionSoundURL(const QString& url);
|
||||||
|
|
||||||
|
SharedSoundPointer getCollisionSound();
|
||||||
|
void setCollisionSound(SharedSoundPointer sound) { _collisionSound = sound; }
|
||||||
|
|
||||||
void clearScriptableSettings();
|
void clearScriptableSettings();
|
||||||
|
|
||||||
float getBoomLength() const { return _boomLength; }
|
float getBoomLength() const { return _boomLength; }
|
||||||
|
@ -309,7 +310,7 @@ private:
|
||||||
void simulate(float deltaTime);
|
void simulate(float deltaTime);
|
||||||
void updateFromTrackers(float deltaTime);
|
void updateFromTrackers(float deltaTime);
|
||||||
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override;
|
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override;
|
||||||
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f) override;
|
virtual void renderBody(RenderArgs* renderArgs, float glowLevel = 0.0f) override;
|
||||||
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const override;
|
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const override;
|
||||||
void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; setEnableMeshVisible(shouldRender); }
|
void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; setEnableMeshVisible(shouldRender); }
|
||||||
bool getShouldRenderLocally() const { return _shouldRender; }
|
bool getShouldRenderLocally() const { return _shouldRender; }
|
||||||
|
@ -365,6 +366,8 @@ private:
|
||||||
quint32 _motionBehaviors;
|
quint32 _motionBehaviors;
|
||||||
QString _collisionSoundURL;
|
QString _collisionSoundURL;
|
||||||
|
|
||||||
|
SharedSoundPointer _collisionSound;
|
||||||
|
|
||||||
MyCharacterController _characterController;
|
MyCharacterController _characterController;
|
||||||
|
|
||||||
AvatarWeakPointer _lookAtTargetAvatar;
|
AvatarWeakPointer _lookAtTargetAvatar;
|
||||||
|
|
|
@ -85,12 +85,23 @@ Rig::CharacterControllerState convertCharacterControllerState(CharacterControlle
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Called within Model::simulate call, below.
|
// Called within Model::simulate call, below.
|
||||||
void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
||||||
const FBXGeometry& geometry = getFBXGeometry();
|
const FBXGeometry& geometry = getFBXGeometry();
|
||||||
|
|
||||||
Head* head = _owningAvatar->getHead();
|
Head* head = _owningAvatar->getHead();
|
||||||
|
|
||||||
|
|
||||||
|
// make sure lookAt is not too close to face (avoid crosseyes)
|
||||||
|
glm::vec3 lookAt = _owningAvatar->isMyAvatar() ? head->getLookAtPosition() : head->getCorrectedLookAtPosition();
|
||||||
|
glm::vec3 focusOffset = lookAt - _owningAvatar->getHead()->getEyePosition();
|
||||||
|
float focusDistance = glm::length(focusOffset);
|
||||||
|
const float MIN_LOOK_AT_FOCUS_DISTANCE = 1.0f;
|
||||||
|
if (focusDistance < MIN_LOOK_AT_FOCUS_DISTANCE && focusDistance > EPSILON) {
|
||||||
|
lookAt = _owningAvatar->getHead()->getEyePosition() + (MIN_LOOK_AT_FOCUS_DISTANCE / focusDistance) * focusOffset;
|
||||||
|
}
|
||||||
|
|
||||||
if (_owningAvatar->isMyAvatar()) {
|
if (_owningAvatar->isMyAvatar()) {
|
||||||
MyAvatar* myAvatar = static_cast<MyAvatar*>(_owningAvatar);
|
MyAvatar* myAvatar = static_cast<MyAvatar*>(_owningAvatar);
|
||||||
|
|
||||||
|
@ -164,7 +175,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
||||||
|
|
||||||
Rig::EyeParameters eyeParams;
|
Rig::EyeParameters eyeParams;
|
||||||
eyeParams.worldHeadOrientation = headParams.worldHeadOrientation;
|
eyeParams.worldHeadOrientation = headParams.worldHeadOrientation;
|
||||||
eyeParams.eyeLookAt = head->getLookAtPosition();
|
eyeParams.eyeLookAt = lookAt;
|
||||||
eyeParams.eyeSaccade = head->getSaccade();
|
eyeParams.eyeSaccade = head->getSaccade();
|
||||||
eyeParams.modelRotation = getRotation();
|
eyeParams.modelRotation = getRotation();
|
||||||
eyeParams.modelTranslation = getTranslation();
|
eyeParams.modelTranslation = getTranslation();
|
||||||
|
@ -196,8 +207,8 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
||||||
|
|
||||||
Rig::EyeParameters eyeParams;
|
Rig::EyeParameters eyeParams;
|
||||||
eyeParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame();
|
eyeParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame();
|
||||||
eyeParams.eyeLookAt = head->getCorrectedLookAtPosition();
|
eyeParams.eyeLookAt = lookAt;
|
||||||
eyeParams.eyeSaccade = glm::vec3();
|
eyeParams.eyeSaccade = glm::vec3(0.0f);
|
||||||
eyeParams.modelRotation = getRotation();
|
eyeParams.modelRotation = getRotation();
|
||||||
eyeParams.modelTranslation = getTranslation();
|
eyeParams.modelTranslation = getTranslation();
|
||||||
eyeParams.leftEyeJointIndex = geometry.leftEyeJointIndex;
|
eyeParams.leftEyeJointIndex = geometry.leftEyeJointIndex;
|
||||||
|
|
|
@ -203,7 +203,7 @@ int main(int argc, const char* argv[]) {
|
||||||
Application::shutdownPlugins();
|
Application::shutdownPlugins();
|
||||||
|
|
||||||
qCDebug(interfaceapp, "Normal exit.");
|
qCDebug(interfaceapp, "Normal exit.");
|
||||||
#ifndef DEBUG
|
#if !defined(DEBUG) && !defined(Q_OS_LINUX)
|
||||||
// HACK: exit immediately (don't handle shutdown callbacks) for Release build
|
// HACK: exit immediately (don't handle shutdown callbacks) for Release build
|
||||||
_exit(exitCode);
|
_exit(exitCode);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,32 +13,16 @@
|
||||||
|
|
||||||
#include "AccountScriptingInterface.h"
|
#include "AccountScriptingInterface.h"
|
||||||
|
|
||||||
AccountScriptingInterface::AccountScriptingInterface() {
|
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
|
||||||
connect(&accountManager, &AccountManager::balanceChanged, this,
|
|
||||||
&AccountScriptingInterface::updateBalance);
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountScriptingInterface* AccountScriptingInterface::getInstance() {
|
AccountScriptingInterface* AccountScriptingInterface::getInstance() {
|
||||||
static AccountScriptingInterface sharedInstance;
|
static AccountScriptingInterface sharedInstance;
|
||||||
return &sharedInstance;
|
return &sharedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
float AccountScriptingInterface::getBalance() {
|
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
|
||||||
return accountManager.getAccountInfo().getBalanceInSatoshis();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AccountScriptingInterface::isLoggedIn() {
|
bool AccountScriptingInterface::isLoggedIn() {
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
return accountManager.isLoggedIn();
|
return accountManager.isLoggedIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountScriptingInterface::updateBalance() {
|
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
|
||||||
emit balanceChanged(accountManager.getAccountInfo().getBalanceInSatoshis());
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AccountScriptingInterface::getUsername() {
|
QString AccountScriptingInterface::getUsername() {
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
if (accountManager.isLoggedIn()) {
|
if (accountManager.isLoggedIn()) {
|
||||||
|
|
|
@ -16,17 +16,11 @@
|
||||||
|
|
||||||
class AccountScriptingInterface : public QObject {
|
class AccountScriptingInterface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
AccountScriptingInterface();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void balanceChanged(float newBalance);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
static AccountScriptingInterface* getInstance();
|
static AccountScriptingInterface* getInstance();
|
||||||
float getBalance();
|
|
||||||
QString getUsername();
|
QString getUsername();
|
||||||
bool isLoggedIn();
|
bool isLoggedIn();
|
||||||
void updateBalance();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AccountScriptingInterface_h
|
#endif // hifi_AccountScriptingInterface_h
|
||||||
|
|
|
@ -11,8 +11,11 @@
|
||||||
|
|
||||||
#include "MenuScriptingInterface.h"
|
#include "MenuScriptingInterface.h"
|
||||||
|
|
||||||
#include "Menu.h"
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QThread>
|
||||||
|
|
||||||
#include <MenuItemProperties.h>
|
#include <MenuItemProperties.h>
|
||||||
|
#include "Menu.h"
|
||||||
|
|
||||||
MenuScriptingInterface* MenuScriptingInterface::getInstance() {
|
MenuScriptingInterface* MenuScriptingInterface::getInstance() {
|
||||||
static MenuScriptingInterface sharedInstance;
|
static MenuScriptingInterface sharedInstance;
|
||||||
|
@ -36,6 +39,9 @@ void MenuScriptingInterface::removeMenu(const QString& menu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MenuScriptingInterface::menuExists(const QString& menu) {
|
bool MenuScriptingInterface::menuExists(const QString& menu) {
|
||||||
|
if (QThread::currentThread() == qApp->thread()) {
|
||||||
|
return Menu::getInstance()->menuExists(menu);
|
||||||
|
}
|
||||||
bool result;
|
bool result;
|
||||||
QMetaObject::invokeMethod(Menu::getInstance(), "menuExists", Qt::BlockingQueuedConnection,
|
QMetaObject::invokeMethod(Menu::getInstance(), "menuExists", Qt::BlockingQueuedConnection,
|
||||||
Q_RETURN_ARG(bool, result),
|
Q_RETURN_ARG(bool, result),
|
||||||
|
@ -76,11 +82,14 @@ void MenuScriptingInterface::removeMenuItem(const QString& menu, const QString&
|
||||||
};
|
};
|
||||||
|
|
||||||
bool MenuScriptingInterface::menuItemExists(const QString& menu, const QString& menuitem) {
|
bool MenuScriptingInterface::menuItemExists(const QString& menu, const QString& menuitem) {
|
||||||
|
if (QThread::currentThread() == qApp->thread()) {
|
||||||
|
return Menu::getInstance()->menuItemExists(menu, menuitem);
|
||||||
|
}
|
||||||
bool result;
|
bool result;
|
||||||
QMetaObject::invokeMethod(Menu::getInstance(), "menuItemExists", Qt::BlockingQueuedConnection,
|
QMetaObject::invokeMethod(Menu::getInstance(), "menuItemExists", Qt::BlockingQueuedConnection,
|
||||||
Q_RETURN_ARG(bool, result),
|
Q_RETURN_ARG(bool, result),
|
||||||
Q_ARG(const QString&, menu),
|
Q_ARG(const QString&, menu),
|
||||||
Q_ARG(const QString&, menuitem));
|
Q_ARG(const QString&, menuitem));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +110,9 @@ void MenuScriptingInterface::removeActionGroup(const QString& groupName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
|
bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
|
||||||
|
if (QThread::currentThread() == qApp->thread()) {
|
||||||
|
return Menu::getInstance()->isOptionChecked(menuOption);
|
||||||
|
}
|
||||||
bool result;
|
bool result;
|
||||||
QMetaObject::invokeMethod(Menu::getInstance(), "isOptionChecked", Qt::BlockingQueuedConnection,
|
QMetaObject::invokeMethod(Menu::getInstance(), "isOptionChecked", Qt::BlockingQueuedConnection,
|
||||||
Q_RETURN_ARG(bool, result),
|
Q_RETURN_ARG(bool, result),
|
||||||
|
@ -109,7 +121,7 @@ bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuScriptingInterface::setIsOptionChecked(const QString& menuOption, bool isChecked) {
|
void MenuScriptingInterface::setIsOptionChecked(const QString& menuOption, bool isChecked) {
|
||||||
QMetaObject::invokeMethod(Menu::getInstance(), "setIsOptionChecked", Qt::BlockingQueuedConnection,
|
QMetaObject::invokeMethod(Menu::getInstance(), "setIsOptionChecked",
|
||||||
Q_ARG(const QString&, menuOption),
|
Q_ARG(const QString&, menuOption),
|
||||||
Q_ARG(bool, isChecked));
|
Q_ARG(bool, isChecked));
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "AddressBarDialog.h"
|
#include "AddressBarDialog.h"
|
||||||
|
#include "Application.h"
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
@ -50,6 +51,16 @@ void AddressBarDialog::loadAddress(const QString& address) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddressBarDialog::loadHome() {
|
||||||
|
qDebug() << "Called LoadHome";
|
||||||
|
QString homeLocation = qApp->getBookmarks()->addressForBookmark(Bookmarks::HOME_BOOKMARK);
|
||||||
|
const QString DEFAULT_HOME_LOCATION = "localhost";
|
||||||
|
if (homeLocation == "") {
|
||||||
|
homeLocation = DEFAULT_HOME_LOCATION;
|
||||||
|
}
|
||||||
|
DependencyManager::get<AddressManager>()->handleLookupString(homeLocation);
|
||||||
|
}
|
||||||
|
|
||||||
void AddressBarDialog::loadBack() {
|
void AddressBarDialog::loadBack() {
|
||||||
qDebug() << "Called LoadBack";
|
qDebug() << "Called LoadBack";
|
||||||
DependencyManager::get<AddressManager>()->goBack();
|
DependencyManager::get<AddressManager>()->goBack();
|
||||||
|
|
|
@ -36,6 +36,7 @@ protected:
|
||||||
void hide();
|
void hide();
|
||||||
|
|
||||||
Q_INVOKABLE void loadAddress(const QString& address);
|
Q_INVOKABLE void loadAddress(const QString& address);
|
||||||
|
Q_INVOKABLE void loadHome();
|
||||||
Q_INVOKABLE void loadBack();
|
Q_INVOKABLE void loadBack();
|
||||||
Q_INVOKABLE void loadForward();
|
Q_INVOKABLE void loadForward();
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,12 @@ UpdateDialog::UpdateDialog(QQuickItem* parent) :
|
||||||
|
|
||||||
_releaseNotes = "";
|
_releaseNotes = "";
|
||||||
for (int i = latestVersion; i > currentVersion; i--) {
|
for (int i = latestVersion; i > currentVersion; i--) {
|
||||||
QString releaseNotes = applicationUpdater.data()->getBuildData()[i]["releaseNotes"];
|
if (applicationUpdater.data()->getBuildData().contains(i)) {
|
||||||
releaseNotes.remove("<br />");
|
QString releaseNotes = applicationUpdater.data()->getBuildData()[i]["releaseNotes"];
|
||||||
releaseNotes.remove(QRegExp("^\n+"));
|
releaseNotes.remove("<br />");
|
||||||
_releaseNotes += "\n" + QString().sprintf("%d", i) + "\n" + releaseNotes + "\n";
|
releaseNotes.remove(QRegExp("^\n+"));
|
||||||
|
_releaseNotes += "\n" + QString().sprintf("%d", i) + "\n" + releaseNotes + "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
Base3DOverlay(const Base3DOverlay* base3DOverlay);
|
Base3DOverlay(const Base3DOverlay* base3DOverlay);
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
virtual bool is3D() const { return true; }
|
virtual bool is3D() const override { return true; }
|
||||||
const glm::vec3& getPosition() const { return _transform.getTranslation(); }
|
const glm::vec3& getPosition() const { return _transform.getTranslation(); }
|
||||||
const glm::quat& getRotation() const { return _transform.getRotation(); }
|
const glm::quat& getRotation() const { return _transform.getRotation(); }
|
||||||
const glm::vec3& getScale() const { return _transform.getScale(); }
|
const glm::vec3& getScale() const { return _transform.getScale(); }
|
||||||
|
@ -50,7 +50,7 @@ public:
|
||||||
void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; }
|
void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; }
|
||||||
void setDrawInFront(bool value) { _drawInFront = value; }
|
void setDrawInFront(bool value) { _drawInFront = value; }
|
||||||
|
|
||||||
virtual AABox getBounds() const = 0;
|
virtual AABox getBounds() const override = 0;
|
||||||
|
|
||||||
void setProperties(const QVariantMap& properties) override;
|
void setProperties(const QVariantMap& properties) override;
|
||||||
QVariant getProperty(const QString& property) override;
|
QVariant getProperty(const QString& property) override;
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
QVariant getProperty(const QString& property) override;
|
QVariant getProperty(const QString& property) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void applyTransformTo(Transform& transform, bool force = false);
|
virtual void applyTransformTo(Transform& transform, bool force = false) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Billboard3DOverlay_h
|
#endif // hifi_Billboard3DOverlay_h
|
||||||
|
|
|
@ -19,12 +19,12 @@ class Circle3DOverlay : public Planar3DOverlay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
virtual QString getType() const override { return TYPE; }
|
||||||
|
|
||||||
Circle3DOverlay();
|
Circle3DOverlay();
|
||||||
Circle3DOverlay(const Circle3DOverlay* circle3DOverlay);
|
Circle3DOverlay(const Circle3DOverlay* circle3DOverlay);
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args) override;
|
||||||
virtual const render::ShapeKey getShapeKey() override;
|
virtual const render::ShapeKey getShapeKey() override;
|
||||||
void setProperties(const QVariantMap& properties) override;
|
void setProperties(const QVariantMap& properties) override;
|
||||||
QVariant getProperty(const QString& property) override;
|
QVariant getProperty(const QString& property) override;
|
||||||
|
@ -54,9 +54,9 @@ public:
|
||||||
void setMinorTickMarksColor(const xColor& value) { _minorTickMarksColor = value; }
|
void setMinorTickMarksColor(const xColor& value) { _minorTickMarksColor = value; }
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal);
|
BoxFace& face, glm::vec3& surfaceNormal) override;
|
||||||
|
|
||||||
virtual Circle3DOverlay* createClone() const;
|
virtual Circle3DOverlay* createClone() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float _startAt;
|
float _startAt;
|
||||||
|
|
|
@ -18,15 +18,15 @@ class Cube3DOverlay : public Volume3DOverlay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
virtual QString getType() const override { return TYPE; }
|
||||||
|
|
||||||
Cube3DOverlay() {}
|
Cube3DOverlay() {}
|
||||||
Cube3DOverlay(const Cube3DOverlay* cube3DOverlay);
|
Cube3DOverlay(const Cube3DOverlay* cube3DOverlay);
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args) override;
|
||||||
virtual const render::ShapeKey getShapeKey() override;
|
virtual const render::ShapeKey getShapeKey() override;
|
||||||
|
|
||||||
virtual Cube3DOverlay* createClone() const;
|
virtual Cube3DOverlay* createClone() const override;
|
||||||
|
|
||||||
float getBorderSize() const { return _borderSize; }
|
float getBorderSize() const { return _borderSize; }
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ void Grid3DOverlay::render(RenderArgs* args) {
|
||||||
// Get the camera position rounded to the nearest major grid line
|
// Get the camera position rounded to the nearest major grid line
|
||||||
// This grid is for UI and should lie on worldlines
|
// This grid is for UI and should lie on worldlines
|
||||||
auto cameraPosition =
|
auto cameraPosition =
|
||||||
(float)_majorGridEvery * glm::round(args->_viewFrustum->getPosition() / (float)_majorGridEvery);
|
(float)_majorGridEvery * glm::round(args->getViewFrustum().getPosition() / (float)_majorGridEvery);
|
||||||
|
|
||||||
position += glm::vec3(cameraPosition.x, 0.0f, cameraPosition.z);
|
position += glm::vec3(cameraPosition.x, 0.0f, cameraPosition.z);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,22 +19,22 @@ class Grid3DOverlay : public Planar3DOverlay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
virtual QString getType() const override { return TYPE; }
|
||||||
|
|
||||||
Grid3DOverlay();
|
Grid3DOverlay();
|
||||||
Grid3DOverlay(const Grid3DOverlay* grid3DOverlay);
|
Grid3DOverlay(const Grid3DOverlay* grid3DOverlay);
|
||||||
|
|
||||||
virtual AABox getBounds() const;
|
virtual AABox getBounds() const override;
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args) override;
|
||||||
virtual const render::ShapeKey getShapeKey() override;
|
virtual const render::ShapeKey getShapeKey() override;
|
||||||
void setProperties(const QVariantMap& properties) override;
|
void setProperties(const QVariantMap& properties) override;
|
||||||
QVariant getProperty(const QString& property) override;
|
QVariant getProperty(const QString& property) override;
|
||||||
|
|
||||||
virtual Grid3DOverlay* createClone() const;
|
virtual Grid3DOverlay* createClone() const override;
|
||||||
|
|
||||||
// Grids are UI tools, and may not be intersected (pickable)
|
// Grids are UI tools, and may not be intersected (pickable)
|
||||||
virtual bool findRayIntersection(const glm::vec3&, const glm::vec3&, float&, BoxFace&, glm::vec3&) { return false; }
|
virtual bool findRayIntersection(const glm::vec3&, const glm::vec3&, float&, BoxFace&, glm::vec3&) override { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateGrid();
|
void updateGrid();
|
||||||
|
|
|
@ -22,14 +22,14 @@ class Image3DOverlay : public Billboard3DOverlay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
virtual QString getType() const override { return TYPE; }
|
||||||
|
|
||||||
Image3DOverlay();
|
Image3DOverlay();
|
||||||
Image3DOverlay(const Image3DOverlay* image3DOverlay);
|
Image3DOverlay(const Image3DOverlay* image3DOverlay);
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args) override;
|
||||||
|
|
||||||
virtual void update(float deltatime);
|
virtual void update(float deltatime) override;
|
||||||
|
|
||||||
virtual const render::ShapeKey getShapeKey() override;
|
virtual const render::ShapeKey getShapeKey() override;
|
||||||
|
|
||||||
|
@ -41,9 +41,9 @@ public:
|
||||||
QVariant getProperty(const QString& property) override;
|
QVariant getProperty(const QString& property) override;
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal);
|
BoxFace& face, glm::vec3& surfaceNormal) override;
|
||||||
|
|
||||||
virtual Image3DOverlay* createClone() const;
|
virtual Image3DOverlay* createClone() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _url;
|
QString _url;
|
||||||
|
|
|
@ -18,14 +18,14 @@ class Line3DOverlay : public Base3DOverlay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
virtual QString getType() const override { return TYPE; }
|
||||||
|
|
||||||
Line3DOverlay();
|
Line3DOverlay();
|
||||||
Line3DOverlay(const Line3DOverlay* line3DOverlay);
|
Line3DOverlay(const Line3DOverlay* line3DOverlay);
|
||||||
~Line3DOverlay();
|
~Line3DOverlay();
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args) override;
|
||||||
virtual const render::ShapeKey getShapeKey() override;
|
virtual const render::ShapeKey getShapeKey() override;
|
||||||
virtual AABox getBounds() const;
|
virtual AABox getBounds() const override;
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
const glm::vec3& getStart() const { return _start; }
|
const glm::vec3& getStart() const { return _start; }
|
||||||
|
@ -38,7 +38,7 @@ public:
|
||||||
void setProperties(const QVariantMap& properties) override;
|
void setProperties(const QVariantMap& properties) override;
|
||||||
QVariant getProperty(const QString& property) override;
|
QVariant getProperty(const QString& property) override;
|
||||||
|
|
||||||
virtual Line3DOverlay* createClone() const;
|
virtual Line3DOverlay* createClone() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 _start;
|
glm::vec3 _start;
|
||||||
|
|
|
@ -37,10 +37,10 @@ void LocalModelsOverlay::render(RenderArgs* args) {
|
||||||
auto batch = args ->_batch;
|
auto batch = args ->_batch;
|
||||||
|
|
||||||
Transform transform = Transform();
|
Transform transform = Transform();
|
||||||
transform.setTranslation(args->_viewFrustum->getPosition() + getPosition());
|
transform.setTranslation(args->getViewFrustum().getPosition() + getPosition());
|
||||||
batch->setViewTransform(transform);
|
batch->setViewTransform(transform);
|
||||||
_entityTreeRenderer->render(args);
|
_entityTreeRenderer->render(args);
|
||||||
transform.setTranslation(args->_viewFrustum->getPosition());
|
transform.setTranslation(args->getViewFrustum().getPosition());
|
||||||
batch->setViewTransform(transform);
|
batch->setViewTransform(transform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,24 +20,24 @@ class ModelOverlay : public Volume3DOverlay {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
virtual QString getType() const override { return TYPE; }
|
||||||
|
|
||||||
ModelOverlay();
|
ModelOverlay();
|
||||||
ModelOverlay(const ModelOverlay* modelOverlay);
|
ModelOverlay(const ModelOverlay* modelOverlay);
|
||||||
|
|
||||||
virtual void update(float deltatime);
|
virtual void update(float deltatime) override;
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args) override;
|
||||||
void setProperties(const QVariantMap& properties) override;
|
void setProperties(const QVariantMap& properties) override;
|
||||||
QVariant getProperty(const QString& property) override;
|
QVariant getProperty(const QString& property) override;
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal);
|
BoxFace& face, glm::vec3& surfaceNormal) override;
|
||||||
virtual bool findRayIntersectionExtraInfo(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findRayIntersectionExtraInfo(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal, QString& extraInfo);
|
float& distance, BoxFace& face, glm::vec3& surfaceNormal, QString& extraInfo) override;
|
||||||
|
|
||||||
virtual ModelOverlay* createClone() const;
|
virtual ModelOverlay* createClone() const override;
|
||||||
|
|
||||||
virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) override;
|
||||||
virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,9 @@ public:
|
||||||
Overlay2D() {}
|
Overlay2D() {}
|
||||||
Overlay2D(const Overlay2D* overlay2D);
|
Overlay2D(const Overlay2D* overlay2D);
|
||||||
|
|
||||||
virtual AABox getBounds() const;
|
virtual AABox getBounds() const override;
|
||||||
|
|
||||||
virtual bool is3D() const { return false; }
|
virtual bool is3D() const override { return false; }
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
int getX() const { return _bounds.x(); }
|
int getX() const { return _bounds.x(); }
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
Planar3DOverlay();
|
Planar3DOverlay();
|
||||||
Planar3DOverlay(const Planar3DOverlay* planar3DOverlay);
|
Planar3DOverlay(const Planar3DOverlay* planar3DOverlay);
|
||||||
|
|
||||||
virtual AABox getBounds() const;
|
virtual AABox getBounds() const override;
|
||||||
|
|
||||||
glm::vec2 getDimensions() const { return _dimensions; }
|
glm::vec2 getDimensions() const { return _dimensions; }
|
||||||
void setDimensions(float value) { _dimensions = glm::vec2(value); }
|
void setDimensions(float value) { _dimensions = glm::vec2(value); }
|
||||||
|
@ -30,7 +30,7 @@ public:
|
||||||
QVariant getProperty(const QString& property) override;
|
QVariant getProperty(const QString& property) override;
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal);
|
BoxFace& face, glm::vec3& surfaceNormal) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
glm::vec2 _dimensions;
|
glm::vec2 _dimensions;
|
||||||
|
|
|
@ -18,16 +18,16 @@ class Rectangle3DOverlay : public Planar3DOverlay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
virtual QString getType() const override { return TYPE; }
|
||||||
|
|
||||||
Rectangle3DOverlay();
|
Rectangle3DOverlay();
|
||||||
Rectangle3DOverlay(const Rectangle3DOverlay* rectangle3DOverlay);
|
Rectangle3DOverlay(const Rectangle3DOverlay* rectangle3DOverlay);
|
||||||
~Rectangle3DOverlay();
|
~Rectangle3DOverlay();
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args) override;
|
||||||
virtual const render::ShapeKey getShapeKey() override;
|
virtual const render::ShapeKey getShapeKey() override;
|
||||||
void setProperties(const QVariantMap& properties) override;
|
void setProperties(const QVariantMap& properties) override;
|
||||||
|
|
||||||
virtual Rectangle3DOverlay* createClone() const;
|
virtual Rectangle3DOverlay* createClone() const override;
|
||||||
private:
|
private:
|
||||||
int _geometryCacheID;
|
int _geometryCacheID;
|
||||||
glm::vec2 _previousHalfDimensions;
|
glm::vec2 _previousHalfDimensions;
|
||||||
|
|
|
@ -18,15 +18,15 @@ class Sphere3DOverlay : public Volume3DOverlay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
virtual QString getType() const override { return TYPE; }
|
||||||
|
|
||||||
Sphere3DOverlay() {}
|
Sphere3DOverlay() {}
|
||||||
Sphere3DOverlay(const Sphere3DOverlay* Sphere3DOverlay);
|
Sphere3DOverlay(const Sphere3DOverlay* Sphere3DOverlay);
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args) override;
|
||||||
virtual const render::ShapeKey getShapeKey() override;
|
virtual const render::ShapeKey getShapeKey() override;
|
||||||
|
|
||||||
virtual Sphere3DOverlay* createClone() const;
|
virtual Sphere3DOverlay* createClone() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,14 @@ void Text3DOverlay::render(RenderArgs* args) {
|
||||||
|
|
||||||
glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR,
|
glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR,
|
||||||
_color.blue / MAX_COLOR, getTextAlpha() };
|
_color.blue / MAX_COLOR, getTextAlpha() };
|
||||||
|
|
||||||
|
// FIXME: Factor out textRenderer so that Text3DOverlay overlay parts can be grouped by pipeline
|
||||||
|
// for a gpu performance increase. Currently,
|
||||||
|
// Text renderer sets its own pipeline,
|
||||||
_textRenderer->draw(batch, 0, 0, _text, textColor, glm::vec2(-1.0f), getDrawInFront());
|
_textRenderer->draw(batch, 0, 0, _text, textColor, glm::vec2(-1.0f), getDrawInFront());
|
||||||
|
// so before we continue, we must reset the pipeline
|
||||||
|
batch.setPipeline(args->_pipeline->pipeline);
|
||||||
|
args->_pipeline->prepare(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
const render::ShapeKey Text3DOverlay::getShapeKey() {
|
const render::ShapeKey Text3DOverlay::getShapeKey() {
|
||||||
|
|
|
@ -22,14 +22,14 @@ class Text3DOverlay : public Billboard3DOverlay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
virtual QString getType() const override { return TYPE; }
|
||||||
|
|
||||||
Text3DOverlay();
|
Text3DOverlay();
|
||||||
Text3DOverlay(const Text3DOverlay* text3DOverlay);
|
Text3DOverlay(const Text3DOverlay* text3DOverlay);
|
||||||
~Text3DOverlay();
|
~Text3DOverlay();
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args) override;
|
||||||
|
|
||||||
virtual void update(float deltatime);
|
virtual void update(float deltatime) override;
|
||||||
|
|
||||||
virtual const render::ShapeKey getShapeKey() override;
|
virtual const render::ShapeKey getShapeKey() override;
|
||||||
|
|
||||||
|
@ -59,9 +59,9 @@ public:
|
||||||
QSizeF textSize(const QString& test) const; // Meters
|
QSizeF textSize(const QString& test) const; // Meters
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal);
|
BoxFace& face, glm::vec3& surfaceNormal) override;
|
||||||
|
|
||||||
virtual Text3DOverlay* createClone() const;
|
virtual Text3DOverlay* createClone() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextRenderer3D* _textRenderer = nullptr;
|
TextRenderer3D* _textRenderer = nullptr;
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
Volume3DOverlay() {}
|
Volume3DOverlay() {}
|
||||||
Volume3DOverlay(const Volume3DOverlay* volume3DOverlay);
|
Volume3DOverlay(const Volume3DOverlay* volume3DOverlay);
|
||||||
|
|
||||||
virtual AABox getBounds() const;
|
virtual AABox getBounds() const override;
|
||||||
|
|
||||||
const glm::vec3& getDimensions() const { return _localBoundingBox.getDimensions(); }
|
const glm::vec3& getDimensions() const { return _localBoundingBox.getDimensions(); }
|
||||||
void setDimensions(float value) { _localBoundingBox.setBox(glm::vec3(-value / 2.0f), value); }
|
void setDimensions(float value) { _localBoundingBox.setBox(glm::vec3(-value / 2.0f), value); }
|
||||||
|
@ -30,7 +30,7 @@ public:
|
||||||
QVariant getProperty(const QString& property) override;
|
QVariant getProperty(const QString& property) override;
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal);
|
BoxFace& face, glm::vec3& surfaceNormal) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Centered local bounding box
|
// Centered local bounding box
|
||||||
|
|
|
@ -18,16 +18,16 @@ class Web3DOverlay : public Billboard3DOverlay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString const TYPE;
|
static QString const TYPE;
|
||||||
virtual QString getType() const { return TYPE; }
|
virtual QString getType() const override { return TYPE; }
|
||||||
|
|
||||||
Web3DOverlay();
|
Web3DOverlay();
|
||||||
Web3DOverlay(const Web3DOverlay* Web3DOverlay);
|
Web3DOverlay(const Web3DOverlay* Web3DOverlay);
|
||||||
virtual ~Web3DOverlay();
|
virtual ~Web3DOverlay();
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args) override;
|
||||||
virtual const render::ShapeKey getShapeKey() override;
|
virtual const render::ShapeKey getShapeKey() override;
|
||||||
|
|
||||||
virtual void update(float deltatime);
|
virtual void update(float deltatime) override;
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
void setURL(const QString& url);
|
void setURL(const QString& url);
|
||||||
|
@ -36,9 +36,9 @@ public:
|
||||||
QVariant getProperty(const QString& property) override;
|
QVariant getProperty(const QString& property) override;
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal);
|
BoxFace& face, glm::vec3& surfaceNormal) override;
|
||||||
|
|
||||||
virtual Web3DOverlay* createClone() const;
|
virtual Web3DOverlay* createClone() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OffscreenQmlSurface* _webSurface{ nullptr };
|
OffscreenQmlSurface* _webSurface{ nullptr };
|
||||||
|
|
|
@ -36,7 +36,7 @@ AnimationPointer AnimationCache::getAnimation(const QUrl& url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<Resource> AnimationCache::createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
|
QSharedPointer<Resource> AnimationCache::createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
|
||||||
bool delayLoad, const void* extra) {
|
const void* extra) {
|
||||||
return QSharedPointer<Resource>(new Animation(url), &Resource::deleter);
|
return QSharedPointer<Resource>(new Animation(url), &Resource::deleter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual QSharedPointer<Resource> createResource(const QUrl& url,
|
virtual QSharedPointer<Resource> createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
|
||||||
const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra);
|
const void* extra);
|
||||||
private:
|
private:
|
||||||
explicit AnimationCache(QObject* parent = NULL);
|
explicit AnimationCache(QObject* parent = NULL);
|
||||||
virtual ~AnimationCache() { }
|
virtual ~AnimationCache() { }
|
||||||
|
|
|
@ -152,14 +152,6 @@ void Rig::restoreRoleAnimation(const QString& role) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::prefetchAnimation(const QString& url) {
|
|
||||||
|
|
||||||
// This will begin loading the NetworkGeometry for the given URL.
|
|
||||||
// which should speed us up if we request it later via overrideAnimation.
|
|
||||||
auto clipNode = std::make_shared<AnimClip>("prefetch", url, 0, 0, 1.0, false, false);
|
|
||||||
_prefetchedAnimations.push_back(clipNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rig::destroyAnimGraph() {
|
void Rig::destroyAnimGraph() {
|
||||||
_animSkeleton.reset();
|
_animSkeleton.reset();
|
||||||
_animLoader.reset();
|
_animLoader.reset();
|
||||||
|
|
|
@ -94,7 +94,6 @@ public:
|
||||||
QStringList getAnimationRoles() const;
|
QStringList getAnimationRoles() const;
|
||||||
void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
|
void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
|
||||||
void restoreRoleAnimation(const QString& role);
|
void restoreRoleAnimation(const QString& role);
|
||||||
void prefetchAnimation(const QString& url);
|
|
||||||
|
|
||||||
void initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset);
|
void initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset);
|
||||||
void reset(const FBXGeometry& geometry);
|
void reset(const FBXGeometry& geometry);
|
||||||
|
@ -203,8 +202,6 @@ public:
|
||||||
// rig space
|
// rig space
|
||||||
bool getModelRegistrationPoint(glm::vec3& modelRegistrationPointOut) const;
|
bool getModelRegistrationPoint(glm::vec3& modelRegistrationPointOut) const;
|
||||||
|
|
||||||
const glm::vec3& getEyesInRootFrame() const { return _eyesInRootFrame; }
|
|
||||||
|
|
||||||
// rig space
|
// rig space
|
||||||
AnimPose getAbsoluteDefaultPose(int index) const;
|
AnimPose getAbsoluteDefaultPose(int index) const;
|
||||||
|
|
||||||
|
@ -275,7 +272,6 @@ protected:
|
||||||
glm::vec3 _lastFront;
|
glm::vec3 _lastFront;
|
||||||
glm::vec3 _lastPosition;
|
glm::vec3 _lastPosition;
|
||||||
glm::vec3 _lastVelocity;
|
glm::vec3 _lastVelocity;
|
||||||
glm::vec3 _eyesInRootFrame { Vectors::ZERO };
|
|
||||||
|
|
||||||
QUrl _animGraphURL;
|
QUrl _animGraphURL;
|
||||||
std::shared_ptr<AnimNode> _animNode;
|
std::shared_ptr<AnimNode> _animNode;
|
||||||
|
@ -322,7 +318,6 @@ protected:
|
||||||
SimpleMovingAverage _averageLateralSpeed { 10 };
|
SimpleMovingAverage _averageLateralSpeed { 10 };
|
||||||
|
|
||||||
std::map<QString, AnimNode::Pointer> _origRoleAnimations;
|
std::map<QString, AnimNode::Pointer> _origRoleAnimations;
|
||||||
std::vector<AnimNode::Pointer> _prefetchedAnimations;
|
|
||||||
|
|
||||||
bool _lastEnableInverseKinematics { true };
|
bool _lastEnableInverseKinematics { true };
|
||||||
bool _enableInverseKinematics { true };
|
bool _enableInverseKinematics { true };
|
||||||
|
|
|
@ -365,17 +365,9 @@ void AudioInjector::stopAndDeleteLater() {
|
||||||
QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioInjector* AudioInjector::playSound(const QString& soundUrl, const float volume, const float stretchFactor, const glm::vec3 position) {
|
AudioInjector* AudioInjector::playSound(SharedSoundPointer sound, const float volume, const float stretchFactor, const glm::vec3 position) {
|
||||||
if (soundUrl.isEmpty()) {
|
if (!sound || !sound->isReady()) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
|
||||||
auto soundCache = DependencyManager::get<SoundCache>();
|
|
||||||
if (soundCache.isNull()) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
SharedSoundPointer sound = soundCache->getSound(QUrl(soundUrl));
|
|
||||||
if (sound.isNull() || !sound->isReady()) {
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioInjectorOptions options;
|
AudioInjectorOptions options;
|
||||||
|
@ -385,7 +377,7 @@ AudioInjector* AudioInjector::playSound(const QString& soundUrl, const float vol
|
||||||
|
|
||||||
QByteArray samples = sound->getByteArray();
|
QByteArray samples = sound->getByteArray();
|
||||||
if (stretchFactor == 1.0f) {
|
if (stretchFactor == 1.0f) {
|
||||||
return playSoundAndDelete(samples, options, NULL);
|
return playSoundAndDelete(samples, options, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int standardRate = AudioConstants::SAMPLE_RATE;
|
const int standardRate = AudioConstants::SAMPLE_RATE;
|
||||||
|
@ -403,7 +395,7 @@ AudioInjector* AudioInjector::playSound(const QString& soundUrl, const float vol
|
||||||
nInputFrames);
|
nInputFrames);
|
||||||
|
|
||||||
Q_UNUSED(nOutputFrames);
|
Q_UNUSED(nOutputFrames);
|
||||||
return playSoundAndDelete(resampled, options, NULL);
|
return playSoundAndDelete(resampled, options, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioInjector* AudioInjector::playSoundAndDelete(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface) {
|
AudioInjector* AudioInjector::playSoundAndDelete(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface) {
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
|
|
||||||
static AudioInjector* playSoundAndDelete(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface);
|
static AudioInjector* playSoundAndDelete(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface);
|
||||||
static AudioInjector* playSound(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface);
|
static AudioInjector* playSound(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface);
|
||||||
static AudioInjector* playSound(const QString& soundUrl, const float volume, const float stretchFactor, const glm::vec3 position);
|
static AudioInjector* playSound(SharedSoundPointer sound, const float volume, const float stretchFactor, const glm::vec3 position);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void restart();
|
void restart();
|
||||||
|
|
|
@ -35,7 +35,7 @@ SharedSoundPointer SoundCache::getSound(const QUrl& url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<Resource> SoundCache::createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
|
QSharedPointer<Resource> SoundCache::createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
|
||||||
bool delayLoad, const void* extra) {
|
const void* extra) {
|
||||||
qCDebug(audio) << "Requesting sound at" << url.toString();
|
qCDebug(audio) << "Requesting sound at" << url.toString();
|
||||||
return QSharedPointer<Resource>(new Sound(url), &Resource::deleter);
|
return QSharedPointer<Resource>(new Sound(url), &Resource::deleter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,8 @@ public:
|
||||||
Q_INVOKABLE SharedSoundPointer getSound(const QUrl& url);
|
Q_INVOKABLE SharedSoundPointer getSound(const QUrl& url);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QSharedPointer<Resource> createResource(const QUrl& url,
|
virtual QSharedPointer<Resource> createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
|
||||||
const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra);
|
const void* extra);
|
||||||
private:
|
private:
|
||||||
SoundCache(QObject* parent = NULL);
|
SoundCache(QObject* parent = NULL);
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,6 @@ const glm::vec3 DEFAULT_LOCAL_AABOX_CORNER(-0.5f);
|
||||||
const glm::vec3 DEFAULT_LOCAL_AABOX_SCALE(1.0f);
|
const glm::vec3 DEFAULT_LOCAL_AABOX_SCALE(1.0f);
|
||||||
|
|
||||||
const QString AvatarData::FRAME_NAME = "com.highfidelity.recording.AvatarData";
|
const QString AvatarData::FRAME_NAME = "com.highfidelity.recording.AvatarData";
|
||||||
static std::once_flag frameTypeRegistration;
|
|
||||||
|
|
||||||
AvatarData::AvatarData() :
|
AvatarData::AvatarData() :
|
||||||
SpatiallyNestable(NestableType::Avatar, QUuid()),
|
SpatiallyNestable(NestableType::Avatar, QUuid()),
|
||||||
|
@ -1194,10 +1193,15 @@ void AvatarData::sendIdentityPacket() {
|
||||||
|
|
||||||
QByteArray identityData = identityByteArray();
|
QByteArray identityData = identityByteArray();
|
||||||
|
|
||||||
auto identityPacket = NLPacket::create(PacketType::AvatarIdentity, identityData.size());
|
auto packetList = NLPacketList::create(PacketType::AvatarIdentity, QByteArray(), true, true);
|
||||||
identityPacket->write(identityData);
|
packetList->write(identityData);
|
||||||
|
nodeList->eachMatchingNode(
|
||||||
nodeList->broadcastToNodes(std::move(identityPacket), NodeSet() << NodeType::AvatarMixer);
|
[&](const SharedNodePointer& node)->bool {
|
||||||
|
return node->getType() == NodeType::AvatarMixer && node->getActiveSocket();
|
||||||
|
},
|
||||||
|
[&](const SharedNodePointer& node) {
|
||||||
|
nodeList->sendPacketList(std::move(packetList), *node);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::sendBillboardPacket() {
|
void AvatarData::sendBillboardPacket() {
|
||||||
|
|
|
@ -58,7 +58,7 @@ controller::UserInputMapper::UserInputMapper() {
|
||||||
|
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
|
|
||||||
UserInputMapper::~UserInputMapper() {
|
UserInputMapper::~UserInputMapper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ void UserInputMapper::registerDevice(InputDevice::Pointer device) {
|
||||||
recordDeviceOfType(device->getName());
|
recordDeviceOfType(device->getName());
|
||||||
|
|
||||||
qCDebug(controllers) << "Registered input device <" << device->getName() << "> deviceID = " << deviceID;
|
qCDebug(controllers) << "Registered input device <" << device->getName() << "> deviceID = " << deviceID;
|
||||||
|
|
||||||
for (const auto& inputMapping : device->getAvailableInputs()) {
|
for (const auto& inputMapping : device->getAvailableInputs()) {
|
||||||
const auto& input = inputMapping.first;
|
const auto& input = inputMapping.first;
|
||||||
// Ignore aliases
|
// Ignore aliases
|
||||||
|
@ -102,6 +103,7 @@ void UserInputMapper::registerDevice(InputDevice::Pointer device) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_registeredDevices[deviceID] = device;
|
_registeredDevices[deviceID] = device;
|
||||||
|
|
||||||
auto mapping = loadMappings(device->getDefaultMappingConfigs());
|
auto mapping = loadMappings(device->getDefaultMappingConfigs());
|
||||||
if (mapping) {
|
if (mapping) {
|
||||||
_mappingsByDevice[deviceID] = mapping;
|
_mappingsByDevice[deviceID] = mapping;
|
||||||
|
@ -111,15 +113,21 @@ void UserInputMapper::registerDevice(InputDevice::Pointer device) {
|
||||||
emit hardwareChanged();
|
emit hardwareChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME remove the associated device mappings
|
|
||||||
void UserInputMapper::removeDevice(int deviceID) {
|
void UserInputMapper::removeDevice(int deviceID) {
|
||||||
|
|
||||||
Locker locker(_lock);
|
Locker locker(_lock);
|
||||||
auto proxyEntry = _registeredDevices.find(deviceID);
|
auto proxyEntry = _registeredDevices.find(deviceID);
|
||||||
|
|
||||||
if (_registeredDevices.end() == proxyEntry) {
|
if (_registeredDevices.end() == proxyEntry) {
|
||||||
qCWarning(controllers) << "Attempted to remove unknown device " << deviceID;
|
qCWarning(controllers) << "Attempted to remove unknown device " << deviceID;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto proxy = proxyEntry->second;
|
|
||||||
|
auto device = proxyEntry->second;
|
||||||
|
qCDebug(controllers) << "Unregistering input device <" << device->getName() << "> deviceID = " << deviceID;
|
||||||
|
|
||||||
|
unloadMappings(device->getDefaultMappingConfigs());
|
||||||
|
|
||||||
auto mappingsEntry = _mappingsByDevice.find(deviceID);
|
auto mappingsEntry = _mappingsByDevice.find(deviceID);
|
||||||
if (_mappingsByDevice.end() != mappingsEntry) {
|
if (_mappingsByDevice.end() != mappingsEntry) {
|
||||||
disableMapping(mappingsEntry->second);
|
disableMapping(mappingsEntry->second);
|
||||||
|
@ -244,7 +252,7 @@ void UserInputMapper::update(float deltaTime) {
|
||||||
for (auto& channel : _actionStates) {
|
for (auto& channel : _actionStates) {
|
||||||
channel = 0.0f;
|
channel = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& channel : _poseStates) {
|
for (auto& channel : _poseStates) {
|
||||||
channel = Pose();
|
channel = Pose();
|
||||||
}
|
}
|
||||||
|
@ -705,11 +713,10 @@ Mapping::Pointer UserInputMapper::loadMapping(const QString& jsonFile, bool enab
|
||||||
return Mapping::Pointer();
|
return Mapping::Pointer();
|
||||||
}
|
}
|
||||||
// Each mapping only needs to be loaded once
|
// Each mapping only needs to be loaded once
|
||||||
static QSet<QString> loaded;
|
if (_loadedRouteJsonFiles.contains(jsonFile)) {
|
||||||
if (loaded.contains(jsonFile)) {
|
|
||||||
return Mapping::Pointer();
|
return Mapping::Pointer();
|
||||||
}
|
}
|
||||||
loaded.insert(jsonFile);
|
_loadedRouteJsonFiles.insert(jsonFile);
|
||||||
QString json;
|
QString json;
|
||||||
{
|
{
|
||||||
QFile file(jsonFile);
|
QFile file(jsonFile);
|
||||||
|
@ -741,6 +748,18 @@ MappingPointer UserInputMapper::loadMappings(const QStringList& jsonFiles) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UserInputMapper::unloadMappings(const QStringList& jsonFiles) {
|
||||||
|
for (const QString& jsonFile : jsonFiles) {
|
||||||
|
unloadMapping(jsonFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInputMapper::unloadMapping(const QString& jsonFile) {
|
||||||
|
auto entry = _loadedRouteJsonFiles.find(jsonFile);
|
||||||
|
if (entry != _loadedRouteJsonFiles.end()) {
|
||||||
|
_loadedRouteJsonFiles.erase(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const QString JSON_NAME = QStringLiteral("name");
|
static const QString JSON_NAME = QStringLiteral("name");
|
||||||
static const QString JSON_CHANNELS = QStringLiteral("channels");
|
static const QString JSON_CHANNELS = QStringLiteral("channels");
|
||||||
|
|
|
@ -111,9 +111,18 @@ namespace controller {
|
||||||
|
|
||||||
void loadDefaultMapping(uint16 deviceID);
|
void loadDefaultMapping(uint16 deviceID);
|
||||||
void enableMapping(const QString& mappingName, bool enable = true);
|
void enableMapping(const QString& mappingName, bool enable = true);
|
||||||
|
|
||||||
|
void unloadMappings(const QStringList& jsonFiles);
|
||||||
|
void unloadMapping(const QString& jsonFile);
|
||||||
|
|
||||||
float getValue(const Input& input) const;
|
float getValue(const Input& input) const;
|
||||||
Pose getPose(const Input& input) const;
|
Pose getPose(const Input& input) const;
|
||||||
|
|
||||||
|
// perform an action when the UserInputMapper mutex is acquired.
|
||||||
|
using Locker = std::unique_lock<std::recursive_mutex>;
|
||||||
|
template <typename F>
|
||||||
|
void withLock(F&& f) { Locker locker(_lock); f(); }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void actionEvent(int action, float state);
|
void actionEvent(int action, float state);
|
||||||
void inputEvent(int input, float state);
|
void inputEvent(int input, float state);
|
||||||
|
@ -177,7 +186,7 @@ namespace controller {
|
||||||
RouteList _deviceRoutes;
|
RouteList _deviceRoutes;
|
||||||
RouteList _standardRoutes;
|
RouteList _standardRoutes;
|
||||||
|
|
||||||
using Locker = std::unique_lock<std::recursive_mutex>;
|
QSet<QString> _loadedRouteJsonFiles;
|
||||||
|
|
||||||
mutable std::recursive_mutex _lock;
|
mutable std::recursive_mutex _lock;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,11 +13,12 @@
|
||||||
|
|
||||||
using namespace controller;
|
using namespace controller;
|
||||||
float DeadZoneFilter::apply(float value) const {
|
float DeadZoneFilter::apply(float value) const {
|
||||||
float scale = 1.0f / (1.0f - _min);
|
float scale = ((value < 0.0f) ? -1.0f : 1.0f) / (1.0f - _min);
|
||||||
if (std::abs(value) < _min) {
|
float magnitude = std::abs(value);
|
||||||
|
if (magnitude < _min) {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
return (value - _min) * scale;
|
return (magnitude - _min) * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeadZoneFilter::parseParameters(const QJsonValue& parameters) {
|
bool DeadZoneFilter::parseParameters(const QJsonValue& parameters) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue