mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 19:59:28 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into metavoxels
This commit is contained in:
commit
d3fe6f21ef
28 changed files with 243 additions and 95 deletions
|
@ -138,7 +138,11 @@ void Agent::run() {
|
||||||
ThreadedAssignment::commonInit(AGENT_LOGGING_NAME, NodeType::Agent);
|
ThreadedAssignment::commonInit(AGENT_LOGGING_NAME, NodeType::Agent);
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet() << NodeType::AudioMixer << NodeType::AvatarMixer);
|
nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet()
|
||||||
|
<< NodeType::AudioMixer
|
||||||
|
<< NodeType::AvatarMixer
|
||||||
|
<< NodeType::VoxelServer
|
||||||
|
<< NodeType::ParticleServer);
|
||||||
|
|
||||||
// figure out the URL for the script for this agent assignment
|
// figure out the URL for the script for this agent assignment
|
||||||
QString scriptURLString("http://%1:8080/assignment/%2");
|
QString scriptURLString("http://%1:8080/assignment/%2");
|
||||||
|
|
|
@ -76,9 +76,9 @@ void OctreeQueryNode::deleteLater() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* octreeServer, const QUuid& nodeUUID) {
|
void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* octreeServer, SharedNodePointer node) {
|
||||||
// Create octree sending thread...
|
// Create octree sending thread...
|
||||||
_octreeSendThread = new OctreeSendThread(nodeUUID, octreeServer);
|
_octreeSendThread = new OctreeSendThread(octreeServer, node);
|
||||||
_octreeSendThread->initialize(true);
|
_octreeSendThread->initialize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ public:
|
||||||
|
|
||||||
OctreeSceneStats stats;
|
OctreeSceneStats stats;
|
||||||
|
|
||||||
void initializeOctreeSendThread(OctreeServer* octreeServer, const QUuid& nodeUUID);
|
void initializeOctreeSendThread(OctreeServer* octreeServer, SharedNodePointer node);
|
||||||
bool isOctreeSendThreadInitalized() { return _octreeSendThread; }
|
bool isOctreeSendThreadInitalized() { return _octreeSendThread; }
|
||||||
|
|
||||||
void dumpOutOfView();
|
void dumpOutOfView();
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
quint64 startSceneSleepTime = 0;
|
quint64 startSceneSleepTime = 0;
|
||||||
quint64 endSceneSleepTime = 0;
|
quint64 endSceneSleepTime = 0;
|
||||||
|
|
||||||
OctreeSendThread::OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer) :
|
OctreeSendThread::OctreeSendThread(OctreeServer* myServer, SharedNodePointer node) :
|
||||||
_nodeUUID(nodeUUID),
|
|
||||||
_myServer(myServer),
|
_myServer(myServer),
|
||||||
|
_nodeUUID(node->getUUID()),
|
||||||
_packetData(),
|
_packetData(),
|
||||||
_nodeMissingCount(0),
|
_nodeMissingCount(0),
|
||||||
_processLock(),
|
_processLock(),
|
||||||
|
@ -44,51 +44,40 @@ OctreeSendThread::~OctreeSendThread() {
|
||||||
}
|
}
|
||||||
qDebug() << qPrintable(safeServerName) << "server [" << _myServer << "]: client disconnected "
|
qDebug() << qPrintable(safeServerName) << "server [" << _myServer << "]: client disconnected "
|
||||||
"- ending sending thread [" << this << "]";
|
"- ending sending thread [" << this << "]";
|
||||||
OctreeServer::clientDisconnected();
|
OctreeServer::clientDisconnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeSendThread::setIsShuttingDown() {
|
void OctreeSendThread::setIsShuttingDown() {
|
||||||
QMutexLocker locker(&_processLock); // this will cause us to wait till the process loop is complete
|
|
||||||
_isShuttingDown = true;
|
_isShuttingDown = true;
|
||||||
OctreeServer::stopTrackingThread(this);
|
OctreeServer::stopTrackingThread(this);
|
||||||
|
|
||||||
|
// this will cause us to wait till the process loop is complete, we do this after we change _isShuttingDown
|
||||||
|
QMutexLocker locker(&_processLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool OctreeSendThread::process() {
|
bool OctreeSendThread::process() {
|
||||||
|
if (_isShuttingDown) {
|
||||||
|
return false; // exit early if we're shutting down
|
||||||
|
}
|
||||||
|
|
||||||
OctreeServer::didProcess(this);
|
OctreeServer::didProcess(this);
|
||||||
|
|
||||||
float lockWaitElapsedUsec = OctreeServer::SKIP_TIME;
|
float lockWaitElapsedUsec = OctreeServer::SKIP_TIME;
|
||||||
quint64 lockWaitStart = usecTimestampNow();
|
quint64 lockWaitStart = usecTimestampNow();
|
||||||
QMutexLocker locker(&_processLock);
|
_processLock.lock();
|
||||||
quint64 lockWaitEnd = usecTimestampNow();
|
quint64 lockWaitEnd = usecTimestampNow();
|
||||||
lockWaitElapsedUsec = (float)(lockWaitEnd - lockWaitStart);
|
lockWaitElapsedUsec = (float)(lockWaitEnd - lockWaitStart);
|
||||||
OctreeServer::trackProcessWaitTime(lockWaitElapsedUsec);
|
OctreeServer::trackProcessWaitTime(lockWaitElapsedUsec);
|
||||||
|
|
||||||
if (_isShuttingDown) {
|
|
||||||
return false; // exit early if we're shutting down
|
|
||||||
}
|
|
||||||
|
|
||||||
const int MAX_NODE_MISSING_CHECKS = 10;
|
|
||||||
if (_nodeMissingCount > MAX_NODE_MISSING_CHECKS) {
|
|
||||||
qDebug() << "our target node:" << _nodeUUID << "has been missing the last" << _nodeMissingCount
|
|
||||||
<< "times we checked, we are going to stop attempting to send.";
|
|
||||||
return false; // stop processing and shutdown, our node no longer exists
|
|
||||||
}
|
|
||||||
|
|
||||||
quint64 start = usecTimestampNow();
|
quint64 start = usecTimestampNow();
|
||||||
|
|
||||||
// don't do any send processing until the initial load of the octree is complete...
|
// don't do any send processing until the initial load of the octree is complete...
|
||||||
if (_myServer->isInitialLoadComplete()) {
|
if (_myServer->isInitialLoadComplete()) {
|
||||||
|
|
||||||
// see if we can get access to our node, but don't wait on the lock, if the nodeList is busy
|
|
||||||
// it might not return a node that is known, but that's ok we can handle that case.
|
|
||||||
SharedNodePointer node = NodeList::getInstance()->nodeWithUUID(_nodeUUID, false);
|
SharedNodePointer node = NodeList::getInstance()->nodeWithUUID(_nodeUUID, false);
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
_nodeMissingCount = 0;
|
_nodeMissingCount = 0;
|
||||||
OctreeQueryNode* nodeData = NULL;
|
OctreeQueryNode* nodeData = static_cast<OctreeQueryNode*>(node->getLinkedData());
|
||||||
|
|
||||||
nodeData = (OctreeQueryNode*) node->getLinkedData();
|
|
||||||
|
|
||||||
// Sometimes the node data has not yet been linked, in which case we can't really do anything
|
// Sometimes the node data has not yet been linked, in which case we can't really do anything
|
||||||
if (nodeData && !nodeData->isShuttingDown()) {
|
if (nodeData && !nodeData->isShuttingDown()) {
|
||||||
|
@ -97,9 +86,26 @@ bool OctreeSendThread::process() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_nodeMissingCount++;
|
_nodeMissingCount++;
|
||||||
|
const int MANY_FAILED_LOCKS = 1;
|
||||||
|
if (_nodeMissingCount >= MANY_FAILED_LOCKS) {
|
||||||
|
|
||||||
|
QString safeServerName("Octree");
|
||||||
|
if (_myServer) {
|
||||||
|
safeServerName = _myServer->getMyServerName();
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << qPrintable(safeServerName) << "server: sending thread [" << this << "]"
|
||||||
|
<< "failed to get nodeWithUUID() " << _nodeUUID <<". Failed:" << _nodeMissingCount << "times";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_processLock.unlock();
|
||||||
|
|
||||||
|
if (_isShuttingDown) {
|
||||||
|
return false; // exit early if we're shutting down
|
||||||
|
}
|
||||||
|
|
||||||
// Only sleep if we're still running and we got the lock last time we tried, otherwise try to get the lock asap
|
// Only sleep if we're still running and we got the lock last time we tried, otherwise try to get the lock asap
|
||||||
if (isStillRunning()) {
|
if (isStillRunning()) {
|
||||||
// dynamically sleep until we need to fire off the next set of octree elements
|
// dynamically sleep until we need to fire off the next set of octree elements
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
class OctreeSendThread : public GenericThread {
|
class OctreeSendThread : public GenericThread {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer);
|
OctreeSendThread(OctreeServer* myServer, SharedNodePointer node);
|
||||||
virtual ~OctreeSendThread();
|
virtual ~OctreeSendThread();
|
||||||
|
|
||||||
void setIsShuttingDown();
|
void setIsShuttingDown();
|
||||||
|
@ -38,8 +38,8 @@ protected:
|
||||||
virtual bool process();
|
virtual bool process();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QUuid _nodeUUID;
|
|
||||||
OctreeServer* _myServer;
|
OctreeServer* _myServer;
|
||||||
|
QUuid _nodeUUID;
|
||||||
|
|
||||||
int handlePacketSend(const SharedNodePointer& node, OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent);
|
int handlePacketSend(const SharedNodePointer& node, OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent);
|
||||||
int packetDistributor(const SharedNodePointer& node, OctreeQueryNode* nodeData, bool viewFrustumChanged);
|
int packetDistributor(const SharedNodePointer& node, OctreeQueryNode* nodeData, bool viewFrustumChanged);
|
||||||
|
|
|
@ -835,7 +835,7 @@ void OctreeServer::readPendingDatagrams() {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
qDebug() << "calling initializeOctreeSendThread()... node:" << *matchingNode;
|
qDebug() << "calling initializeOctreeSendThread()... node:" << *matchingNode;
|
||||||
}
|
}
|
||||||
nodeData->initializeOctreeSendThread(this, matchingNode->getUUID());
|
nodeData->initializeOctreeSendThread(this, matchingNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (packetType == PacketTypeJurisdictionRequest) {
|
} else if (packetType == PacketTypeJurisdictionRequest) {
|
||||||
|
@ -852,7 +852,9 @@ void OctreeServer::readPendingDatagrams() {
|
||||||
|
|
||||||
void OctreeServer::run() {
|
void OctreeServer::run() {
|
||||||
_safeServerName = getMyServerName();
|
_safeServerName = getMyServerName();
|
||||||
|
|
||||||
// Before we do anything else, create our tree...
|
// Before we do anything else, create our tree...
|
||||||
|
OctreeElement::resetPopulationStatistics();
|
||||||
_tree = createTree();
|
_tree = createTree();
|
||||||
|
|
||||||
// use common init to setup common timers and logging
|
// use common init to setup common timers and logging
|
||||||
|
@ -1158,7 +1160,6 @@ QString OctreeServer::getStatusLink() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeServer::sendStatsPacket() {
|
void OctreeServer::sendStatsPacket() {
|
||||||
|
|
||||||
// TODO: we have too many stats to fit in a single MTU... so for now, we break it into multiple JSON objects and
|
// TODO: we have too many stats to fit in a single MTU... so for now, we break it into multiple JSON objects and
|
||||||
// send them separately. What we really should do is change the NodeList::sendStatsToDomainServer() to handle the
|
// send them separately. What we really should do is change the NodeList::sendStatsToDomainServer() to handle the
|
||||||
// the following features:
|
// the following features:
|
||||||
|
@ -1239,59 +1240,78 @@ QMap<OctreeSendThread*, quint64> OctreeServer::_threadsDidPacketDistributor;
|
||||||
QMap<OctreeSendThread*, quint64> OctreeServer::_threadsDidHandlePacketSend;
|
QMap<OctreeSendThread*, quint64> OctreeServer::_threadsDidHandlePacketSend;
|
||||||
QMap<OctreeSendThread*, quint64> OctreeServer::_threadsDidCallWriteDatagram;
|
QMap<OctreeSendThread*, quint64> OctreeServer::_threadsDidCallWriteDatagram;
|
||||||
|
|
||||||
|
QMutex OctreeServer::_threadsDidProcessMutex;
|
||||||
|
QMutex OctreeServer::_threadsDidPacketDistributorMutex;
|
||||||
|
QMutex OctreeServer::_threadsDidHandlePacketSendMutex;
|
||||||
|
QMutex OctreeServer::_threadsDidCallWriteDatagramMutex;
|
||||||
|
|
||||||
|
|
||||||
void OctreeServer::didProcess(OctreeSendThread* thread) {
|
void OctreeServer::didProcess(OctreeSendThread* thread) {
|
||||||
|
QMutexLocker locker(&_threadsDidProcessMutex);
|
||||||
_threadsDidProcess[thread] = usecTimestampNow();
|
_threadsDidProcess[thread] = usecTimestampNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeServer::didPacketDistributor(OctreeSendThread* thread) {
|
void OctreeServer::didPacketDistributor(OctreeSendThread* thread) {
|
||||||
|
QMutexLocker locker(&_threadsDidPacketDistributorMutex);
|
||||||
_threadsDidPacketDistributor[thread] = usecTimestampNow();
|
_threadsDidPacketDistributor[thread] = usecTimestampNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeServer::didHandlePacketSend(OctreeSendThread* thread) {
|
void OctreeServer::didHandlePacketSend(OctreeSendThread* thread) {
|
||||||
|
QMutexLocker locker(&_threadsDidHandlePacketSendMutex);
|
||||||
_threadsDidHandlePacketSend[thread] = usecTimestampNow();
|
_threadsDidHandlePacketSend[thread] = usecTimestampNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeServer::didCallWriteDatagram(OctreeSendThread* thread) {
|
void OctreeServer::didCallWriteDatagram(OctreeSendThread* thread) {
|
||||||
|
QMutexLocker locker(&_threadsDidCallWriteDatagramMutex);
|
||||||
_threadsDidCallWriteDatagram[thread] = usecTimestampNow();
|
_threadsDidCallWriteDatagram[thread] = usecTimestampNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OctreeServer::stopTrackingThread(OctreeSendThread* thread) {
|
void OctreeServer::stopTrackingThread(OctreeSendThread* thread) {
|
||||||
|
QMutexLocker lockerA(&_threadsDidProcessMutex);
|
||||||
|
QMutexLocker lockerB(&_threadsDidPacketDistributorMutex);
|
||||||
|
QMutexLocker lockerC(&_threadsDidHandlePacketSendMutex);
|
||||||
|
QMutexLocker lockerD(&_threadsDidCallWriteDatagramMutex);
|
||||||
|
|
||||||
_threadsDidProcess.remove(thread);
|
_threadsDidProcess.remove(thread);
|
||||||
_threadsDidPacketDistributor.remove(thread);
|
_threadsDidPacketDistributor.remove(thread);
|
||||||
_threadsDidHandlePacketSend.remove(thread);
|
_threadsDidHandlePacketSend.remove(thread);
|
||||||
|
_threadsDidCallWriteDatagram.remove(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
int howManyThreadsDidSomething(QMap<OctreeSendThread*, quint64>& something, quint64 since) {
|
int howManyThreadsDidSomething(QMutex& mutex, QMap<OctreeSendThread*, quint64>& something, quint64 since) {
|
||||||
if (since == 0) {
|
|
||||||
return something.size();
|
|
||||||
}
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
QMap<OctreeSendThread*, quint64>::const_iterator i = something.constBegin();
|
if (mutex.tryLock()) {
|
||||||
while (i != something.constEnd()) {
|
if (since == 0) {
|
||||||
if (i.value() > since) {
|
count = something.size();
|
||||||
count++;
|
} else {
|
||||||
|
QMap<OctreeSendThread*, quint64>::const_iterator i = something.constBegin();
|
||||||
|
while (i != something.constEnd()) {
|
||||||
|
if (i.value() > since) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
++i;
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int OctreeServer::howManyThreadsDidProcess(quint64 since) {
|
int OctreeServer::howManyThreadsDidProcess(quint64 since) {
|
||||||
return howManyThreadsDidSomething(_threadsDidProcess, since);
|
return howManyThreadsDidSomething(_threadsDidProcessMutex, _threadsDidProcess, since);
|
||||||
}
|
}
|
||||||
|
|
||||||
int OctreeServer::howManyThreadsDidPacketDistributor(quint64 since) {
|
int OctreeServer::howManyThreadsDidPacketDistributor(quint64 since) {
|
||||||
return howManyThreadsDidSomething(_threadsDidPacketDistributor, since);
|
return howManyThreadsDidSomething(_threadsDidPacketDistributorMutex, _threadsDidPacketDistributor, since);
|
||||||
}
|
}
|
||||||
|
|
||||||
int OctreeServer::howManyThreadsDidHandlePacketSend(quint64 since) {
|
int OctreeServer::howManyThreadsDidHandlePacketSend(quint64 since) {
|
||||||
return howManyThreadsDidSomething(_threadsDidHandlePacketSend, since);
|
return howManyThreadsDidSomething(_threadsDidHandlePacketSendMutex, _threadsDidHandlePacketSend, since);
|
||||||
}
|
}
|
||||||
|
|
||||||
int OctreeServer::howManyThreadsDidCallWriteDatagram(quint64 since) {
|
int OctreeServer::howManyThreadsDidCallWriteDatagram(quint64 since) {
|
||||||
return howManyThreadsDidSomething(_threadsDidCallWriteDatagram, since);
|
return howManyThreadsDidSomething(_threadsDidCallWriteDatagramMutex, _threadsDidCallWriteDatagram, since);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -211,6 +211,10 @@ protected:
|
||||||
static QMap<OctreeSendThread*, quint64> _threadsDidHandlePacketSend;
|
static QMap<OctreeSendThread*, quint64> _threadsDidHandlePacketSend;
|
||||||
static QMap<OctreeSendThread*, quint64> _threadsDidCallWriteDatagram;
|
static QMap<OctreeSendThread*, quint64> _threadsDidCallWriteDatagram;
|
||||||
|
|
||||||
|
static QMutex _threadsDidProcessMutex;
|
||||||
|
static QMutex _threadsDidPacketDistributorMutex;
|
||||||
|
static QMutex _threadsDidHandlePacketSendMutex;
|
||||||
|
static QMutex _threadsDidCallWriteDatagramMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __octree_server__OctreeServer__
|
#endif // __octree_server__OctreeServer__
|
||||||
|
|
|
@ -14,12 +14,12 @@
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="3597"/>
|
<location filename="src/Application.cpp" line="3610"/>
|
||||||
<source>Open Script</source>
|
<source>Open Script</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="3598"/>
|
<location filename="src/Application.cpp" line="3611"/>
|
||||||
<source>JavaScript Files (*.js)</source>
|
<source>JavaScript Files (*.js)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -113,18 +113,18 @@
|
||||||
<context>
|
<context>
|
||||||
<name>Menu</name>
|
<name>Menu</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="457"/>
|
<location filename="src/Menu.cpp" line="456"/>
|
||||||
<source>Open .ini config file</source>
|
<source>Open .ini config file</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="459"/>
|
<location filename="src/Menu.cpp" line="458"/>
|
||||||
<location filename="src/Menu.cpp" line="471"/>
|
<location filename="src/Menu.cpp" line="470"/>
|
||||||
<source>Text files (*.ini)</source>
|
<source>Text files (*.ini)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="469"/>
|
<location filename="src/Menu.cpp" line="468"/>
|
||||||
<source>Save .ini config file</source>
|
<source>Save .ini config file</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
|
|
||||||
uniform sampler2DShadow shadowMap;
|
uniform sampler2DShadow shadowMap;
|
||||||
|
|
||||||
|
varying vec4 shadowColor;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
gl_FragColor = gl_Color * mix(vec4(0.8, 0.8, 0.8, 1.0), vec4(1.0, 1.0, 1.0, 1.0),
|
gl_FragColor = mix(shadowColor, gl_Color, shadow2D(shadowMap, gl_TexCoord[0].stp));
|
||||||
shadow2D(shadowMap, gl_TexCoord[0].stp));
|
|
||||||
}
|
}
|
||||||
|
|
28
interface/resources/shaders/shadow_map.vert
Normal file
28
interface/resources/shaders/shadow_map.vert
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// shadow_map.vert
|
||||||
|
// vertex shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 3/27/14.
|
||||||
|
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
varying vec4 shadowColor;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// the shadow color includes only the ambient terms
|
||||||
|
shadowColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient);
|
||||||
|
|
||||||
|
// the normal color includes diffuse
|
||||||
|
vec4 normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||||
|
gl_FrontColor = shadowColor + gl_Color * (gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position)));
|
||||||
|
|
||||||
|
// generate the shadow texture coordinate using the eye position
|
||||||
|
vec4 eyePosition = gl_ModelViewMatrix * gl_Vertex;
|
||||||
|
gl_TexCoord[0] = vec4(dot(gl_EyePlaneS[0], eyePosition), dot(gl_EyePlaneT[0], eyePosition),
|
||||||
|
dot(gl_EyePlaneR[0], eyePosition), 1.0);
|
||||||
|
|
||||||
|
// use the fixed function transform
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
|
@ -1636,6 +1636,8 @@ void Application::updateLOD() {
|
||||||
// adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode
|
// adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode
|
||||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableAutoAdjustLOD) && !isThrottleRendering()) {
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableAutoAdjustLOD) && !isThrottleRendering()) {
|
||||||
Menu::getInstance()->autoAdjustLOD(_fps);
|
Menu::getInstance()->autoAdjustLOD(_fps);
|
||||||
|
} else {
|
||||||
|
Menu::getInstance()->resetLODAdjust();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2676,7 +2678,7 @@ void Application::displayStats() {
|
||||||
|
|
||||||
glm::vec3 avatarPos = _myAvatar->getPosition();
|
glm::vec3 avatarPos = _myAvatar->getPosition();
|
||||||
|
|
||||||
lines = _statsExpanded ? 4 : 3;
|
lines = _statsExpanded ? 5 : 3;
|
||||||
displayStatsBackground(backgroundColor, horizontalOffset, 0, _glWidget->width() - (mirrorEnabled ? 301 : 411) - horizontalOffset, lines * STATS_PELS_PER_LINE + 10);
|
displayStatsBackground(backgroundColor, horizontalOffset, 0, _glWidget->width() - (mirrorEnabled ? 301 : 411) - horizontalOffset, lines * STATS_PELS_PER_LINE + 10);
|
||||||
horizontalOffset += 5;
|
horizontalOffset += 5;
|
||||||
|
|
||||||
|
@ -2713,12 +2715,23 @@ void Application::displayStats() {
|
||||||
|
|
||||||
verticalOffset += STATS_PELS_PER_LINE;
|
verticalOffset += STATS_PELS_PER_LINE;
|
||||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarMixerStats, WHITE_TEXT);
|
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarMixerStats, WHITE_TEXT);
|
||||||
|
|
||||||
|
stringstream downloadStats;
|
||||||
|
downloadStats << "Downloads: ";
|
||||||
|
foreach (Resource* resource, ResourceCache::getLoadingRequests()) {
|
||||||
|
const float MAXIMUM_PERCENTAGE = 100.0f;
|
||||||
|
downloadStats << roundf(resource->getProgress() * MAXIMUM_PERCENTAGE) << "% ";
|
||||||
|
}
|
||||||
|
downloadStats << "(" << ResourceCache::getPendingRequestCount() << " pending)";
|
||||||
|
|
||||||
|
verticalOffset += STATS_PELS_PER_LINE;
|
||||||
|
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, downloadStats.str().c_str(), WHITE_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
verticalOffset = 0;
|
verticalOffset = 0;
|
||||||
horizontalOffset = _glWidget->width() - (mirrorEnabled ? 300 : 410);
|
horizontalOffset = _glWidget->width() - (mirrorEnabled ? 300 : 410);
|
||||||
|
|
||||||
lines = _statsExpanded ? 11 : 3;
|
lines = _statsExpanded ? 12 : 3;
|
||||||
displayStatsBackground(backgroundColor, horizontalOffset, 0, _glWidget->width() - horizontalOffset, lines * STATS_PELS_PER_LINE + 10);
|
displayStatsBackground(backgroundColor, horizontalOffset, 0, _glWidget->width() - horizontalOffset, lines * STATS_PELS_PER_LINE + 10);
|
||||||
horizontalOffset += 5;
|
horizontalOffset += 5;
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,28 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
QString deviceName;
|
||||||
|
if (mode == QAudio::AudioInput) {
|
||||||
|
WAVEINCAPS wic;
|
||||||
|
// first use WAVE_MAPPER to get the default devices manufacturer ID
|
||||||
|
waveInGetDevCaps(WAVE_MAPPER, &wic, sizeof(wic));
|
||||||
|
//Use the received manufacturer id to get the device's real name
|
||||||
|
waveInGetDevCaps(wic.wMid, &wic, sizeof(wic));
|
||||||
|
qDebug() << "input device:" << wic.szPname;
|
||||||
|
deviceName = wic.szPname;
|
||||||
|
} else {
|
||||||
|
WAVEOUTCAPS woc;
|
||||||
|
// first use WAVE_MAPPER to get the default devices manufacturer ID
|
||||||
|
waveOutGetDevCaps(WAVE_MAPPER, &woc, sizeof(woc));
|
||||||
|
//Use the received manufacturer id to get the device's real name
|
||||||
|
waveOutGetDevCaps(woc.wMid, &woc, sizeof(woc));
|
||||||
|
qDebug() << "output device:" << woc.szPname;
|
||||||
|
deviceName = woc.szPname;
|
||||||
|
}
|
||||||
|
return getNamedAudioDeviceForMode(mode, deviceName);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// fallback for failed lookup is the default device
|
// fallback for failed lookup is the default device
|
||||||
return (mode == QAudio::AudioInput) ? QAudioDeviceInfo::defaultInputDevice() : QAudioDeviceInfo::defaultOutputDevice();
|
return (mode == QAudio::AudioInput) ? QAudioDeviceInfo::defaultInputDevice() : QAudioDeviceInfo::defaultOutputDevice();
|
||||||
|
@ -500,7 +522,7 @@ void Audio::handleAudioInput() {
|
||||||
if (audioMixer && audioMixer->getActiveSocket()) {
|
if (audioMixer && audioMixer->getActiveSocket()) {
|
||||||
MyAvatar* interfaceAvatar = Application::getInstance()->getAvatar();
|
MyAvatar* interfaceAvatar = Application::getInstance()->getAvatar();
|
||||||
glm::vec3 headPosition = interfaceAvatar->getHead()->getPosition();
|
glm::vec3 headPosition = interfaceAvatar->getHead()->getPosition();
|
||||||
glm::quat headOrientation = interfaceAvatar->getHead()->getOrientation();
|
glm::quat headOrientation = interfaceAvatar->getHead()->getTweakedOrientation();
|
||||||
|
|
||||||
// we need the amount of bytes in the buffer + 1 for type
|
// we need the amount of bytes in the buffer + 1 for type
|
||||||
// + 12 for 3 floats for position + float for bearing + 1 attenuation byte
|
// + 12 for 3 floats for position + float for bearing + 1 attenuation byte
|
||||||
|
@ -840,7 +862,6 @@ bool Audio::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo)
|
||||||
// cleanup any previously initialized device
|
// cleanup any previously initialized device
|
||||||
if (_audioOutput) {
|
if (_audioOutput) {
|
||||||
_audioOutput->stop();
|
_audioOutput->stop();
|
||||||
disconnect(_outputDevice, 0, 0, 0);
|
|
||||||
_outputDevice = NULL;
|
_outputDevice = NULL;
|
||||||
|
|
||||||
delete _audioOutput;
|
delete _audioOutput;
|
||||||
|
|
|
@ -62,7 +62,8 @@ Menu* Menu::getInstance() {
|
||||||
const ViewFrustumOffset DEFAULT_FRUSTUM_OFFSET = {-135.0f, 0.0f, 0.0f, 25.0f, 0.0f};
|
const ViewFrustumOffset DEFAULT_FRUSTUM_OFFSET = {-135.0f, 0.0f, 0.0f, 25.0f, 0.0f};
|
||||||
const float DEFAULT_FACESHIFT_EYE_DEFLECTION = 0.25f;
|
const float DEFAULT_FACESHIFT_EYE_DEFLECTION = 0.25f;
|
||||||
const float DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER = 1.0f;
|
const float DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER = 1.0f;
|
||||||
const int FIVE_SECONDS_OF_FRAMES = 5 * 60;
|
const int ONE_SECOND_OF_FRAMES = 60;
|
||||||
|
const int FIVE_SECONDS_OF_FRAMES = 5 * ONE_SECOND_OF_FRAMES;
|
||||||
|
|
||||||
Menu::Menu() :
|
Menu::Menu() :
|
||||||
_actionHash(),
|
_actionHash(),
|
||||||
|
@ -82,6 +83,7 @@ Menu::Menu() :
|
||||||
_lastAdjust(usecTimestampNow()),
|
_lastAdjust(usecTimestampNow()),
|
||||||
_lastAvatarDetailDrop(usecTimestampNow()),
|
_lastAvatarDetailDrop(usecTimestampNow()),
|
||||||
_fpsAverage(FIVE_SECONDS_OF_FRAMES),
|
_fpsAverage(FIVE_SECONDS_OF_FRAMES),
|
||||||
|
_fastFPSAverage(ONE_SECOND_OF_FRAMES),
|
||||||
_loginAction(NULL)
|
_loginAction(NULL)
|
||||||
{
|
{
|
||||||
Application *appInstance = Application::getInstance();
|
Application *appInstance = Application::getInstance();
|
||||||
|
@ -391,8 +393,6 @@ void Menu::loadSettings(QSettings* settings) {
|
||||||
_maxVoxels = loadSetting(settings, "maxVoxels", DEFAULT_MAX_VOXELS_PER_SYSTEM);
|
_maxVoxels = loadSetting(settings, "maxVoxels", DEFAULT_MAX_VOXELS_PER_SYSTEM);
|
||||||
_maxVoxelPacketsPerSecond = loadSetting(settings, "maxVoxelsPPS", DEFAULT_MAX_VOXEL_PPS);
|
_maxVoxelPacketsPerSecond = loadSetting(settings, "maxVoxelsPPS", DEFAULT_MAX_VOXEL_PPS);
|
||||||
_voxelSizeScale = loadSetting(settings, "voxelSizeScale", DEFAULT_OCTREE_SIZE_SCALE);
|
_voxelSizeScale = loadSetting(settings, "voxelSizeScale", DEFAULT_OCTREE_SIZE_SCALE);
|
||||||
_avatarLODDistanceMultiplier = loadSetting(settings, "avatarLODDistanceMultiplier",
|
|
||||||
DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER);
|
|
||||||
_boundaryLevelAdjust = loadSetting(settings, "boundaryLevelAdjust", 0);
|
_boundaryLevelAdjust = loadSetting(settings, "boundaryLevelAdjust", 0);
|
||||||
|
|
||||||
settings->beginGroup("View Frustum Offset Camera");
|
settings->beginGroup("View Frustum Offset Camera");
|
||||||
|
@ -432,7 +432,6 @@ void Menu::saveSettings(QSettings* settings) {
|
||||||
settings->setValue("maxVoxels", _maxVoxels);
|
settings->setValue("maxVoxels", _maxVoxels);
|
||||||
settings->setValue("maxVoxelsPPS", _maxVoxelPacketsPerSecond);
|
settings->setValue("maxVoxelsPPS", _maxVoxelPacketsPerSecond);
|
||||||
settings->setValue("voxelSizeScale", _voxelSizeScale);
|
settings->setValue("voxelSizeScale", _voxelSizeScale);
|
||||||
settings->setValue("avatarLODDistanceMultiplier", _avatarLODDistanceMultiplier);
|
|
||||||
settings->setValue("boundaryLevelAdjust", _boundaryLevelAdjust);
|
settings->setValue("boundaryLevelAdjust", _boundaryLevelAdjust);
|
||||||
settings->beginGroup("View Frustum Offset Camera");
|
settings->beginGroup("View Frustum Offset Camera");
|
||||||
settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw);
|
settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw);
|
||||||
|
@ -1192,19 +1191,24 @@ void Menu::autoAdjustLOD(float currentFPS) {
|
||||||
currentFPS = ASSUMED_FPS;
|
currentFPS = ASSUMED_FPS;
|
||||||
}
|
}
|
||||||
_fpsAverage.updateAverage(currentFPS);
|
_fpsAverage.updateAverage(currentFPS);
|
||||||
|
_fastFPSAverage.updateAverage(currentFPS);
|
||||||
|
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
|
|
||||||
if (_fpsAverage.getAverage() < ADJUST_LOD_DOWN_FPS) {
|
const quint64 ADJUST_AVATAR_LOD_DOWN_DELAY = 1000 * 1000;
|
||||||
if (now - _lastAvatarDetailDrop > ADJUST_LOD_DOWN_DELAY) {
|
if (_fastFPSAverage.getAverage() < ADJUST_LOD_DOWN_FPS) {
|
||||||
|
if (now - _lastAvatarDetailDrop > ADJUST_AVATAR_LOD_DOWN_DELAY) {
|
||||||
// attempt to lower the detail in proportion to the fps difference
|
// attempt to lower the detail in proportion to the fps difference
|
||||||
float targetFps = (ADJUST_LOD_DOWN_FPS + ADJUST_LOD_UP_FPS) * 0.5f;
|
float targetFps = (ADJUST_LOD_DOWN_FPS + ADJUST_LOD_UP_FPS) * 0.5f;
|
||||||
_avatarLODDistanceMultiplier *= (targetFps / _fpsAverage.getAverage());
|
float averageFps = _fastFPSAverage.getAverage();
|
||||||
|
const float MAXIMUM_MULTIPLIER_SCALE = 2.0f;
|
||||||
|
_avatarLODDistanceMultiplier *= (averageFps < EPSILON) ? MAXIMUM_MULTIPLIER_SCALE :
|
||||||
|
qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps);
|
||||||
_lastAvatarDetailDrop = now;
|
_lastAvatarDetailDrop = now;
|
||||||
}
|
}
|
||||||
} else if (_fpsAverage.getAverage() > ADJUST_LOD_UP_FPS) {
|
} else if (_fastFPSAverage.getAverage() > ADJUST_LOD_UP_FPS) {
|
||||||
// let the detail level creep slowly upwards
|
// let the detail level creep slowly upwards
|
||||||
const float DISTANCE_DECREASE_RATE = 0.01f;
|
const float DISTANCE_DECREASE_RATE = 0.02f;
|
||||||
const float MINIMUM_DISTANCE_MULTIPLIER = 0.1f;
|
const float MINIMUM_DISTANCE_MULTIPLIER = 0.1f;
|
||||||
_avatarLODDistanceMultiplier = qMax(MINIMUM_DISTANCE_MULTIPLIER,
|
_avatarLODDistanceMultiplier = qMax(MINIMUM_DISTANCE_MULTIPLIER,
|
||||||
_avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE);
|
_avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE);
|
||||||
|
@ -1245,6 +1249,12 @@ void Menu::autoAdjustLOD(float currentFPS) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::resetLODAdjust() {
|
||||||
|
_fpsAverage.reset();
|
||||||
|
_fastFPSAverage.reset();
|
||||||
|
_lastAvatarDetailDrop = _lastAdjust = usecTimestampNow();
|
||||||
|
}
|
||||||
|
|
||||||
void Menu::setVoxelSizeScale(float sizeScale) {
|
void Menu::setVoxelSizeScale(float sizeScale) {
|
||||||
_voxelSizeScale = sizeScale;
|
_voxelSizeScale = sizeScale;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,8 +66,6 @@ public:
|
||||||
static Menu* getInstance();
|
static Menu* getInstance();
|
||||||
~Menu();
|
~Menu();
|
||||||
|
|
||||||
bool isOptionChecked(const QString& menuOption);
|
|
||||||
void setIsOptionChecked(const QString& menuOption, bool isChecked);
|
|
||||||
void triggerOption(const QString& menuOption);
|
void triggerOption(const QString& menuOption);
|
||||||
QAction* getActionForOption(const QString& menuOption);
|
QAction* getActionForOption(const QString& menuOption);
|
||||||
|
|
||||||
|
@ -87,6 +85,7 @@ public:
|
||||||
// User Tweakable LOD Items
|
// User Tweakable LOD Items
|
||||||
QString getLODFeedbackText();
|
QString getLODFeedbackText();
|
||||||
void autoAdjustLOD(float currentFPS);
|
void autoAdjustLOD(float currentFPS);
|
||||||
|
void resetLODAdjust();
|
||||||
void setVoxelSizeScale(float sizeScale);
|
void setVoxelSizeScale(float sizeScale);
|
||||||
float getVoxelSizeScale() const { return _voxelSizeScale; }
|
float getVoxelSizeScale() const { return _voxelSizeScale; }
|
||||||
float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
|
float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
|
||||||
|
@ -133,6 +132,8 @@ public slots:
|
||||||
void removeSeparator(const QString& menuName, const QString& separatorName);
|
void removeSeparator(const QString& menuName, const QString& separatorName);
|
||||||
void addMenuItem(const MenuItemProperties& properties);
|
void addMenuItem(const MenuItemProperties& properties);
|
||||||
void removeMenuItem(const QString& menuName, const QString& menuitem);
|
void removeMenuItem(const QString& menuName, const QString& menuitem);
|
||||||
|
bool isOptionChecked(const QString& menuOption);
|
||||||
|
void setIsOptionChecked(const QString& menuOption, bool isChecked);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void aboutApp();
|
void aboutApp();
|
||||||
|
@ -211,6 +212,7 @@ private:
|
||||||
quint64 _lastAdjust;
|
quint64 _lastAdjust;
|
||||||
quint64 _lastAvatarDetailDrop;
|
quint64 _lastAvatarDetailDrop;
|
||||||
SimpleMovingAverage _fpsAverage;
|
SimpleMovingAverage _fpsAverage;
|
||||||
|
SimpleMovingAverage _fastFPSAverage;
|
||||||
QAction* _loginAction;
|
QAction* _loginAction;
|
||||||
QAction* _chatAction;
|
QAction* _chatAction;
|
||||||
};
|
};
|
||||||
|
|
|
@ -397,9 +397,13 @@ void Avatar::renderDisplayName() {
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glm::vec3 textPosition;
|
glm::vec3 textPosition;
|
||||||
getSkeletonModel().getNeckPosition(textPosition);
|
if (getSkeletonModel().getNeckPosition(textPosition)) {
|
||||||
textPosition += getBodyUpDirection() * getHeadHeight() * 1.1f;
|
textPosition += getBodyUpDirection() * getHeadHeight() * 1.1f;
|
||||||
|
} else {
|
||||||
|
const float HEAD_PROPORTION = 0.75f;
|
||||||
|
textPosition = _position + getBodyUpDirection() * (getBillboardSize() * HEAD_PROPORTION);
|
||||||
|
}
|
||||||
|
|
||||||
glTranslatef(textPosition.x, textPosition.y, textPosition.z);
|
glTranslatef(textPosition.x, textPosition.y, textPosition.z);
|
||||||
|
|
||||||
// we need "always facing camera": we must remove the camera rotation from the stack
|
// we need "always facing camera": we must remove the camera rotation from the stack
|
||||||
|
|
|
@ -55,9 +55,6 @@ void Head::reset() {
|
||||||
_faceModel.reset();
|
_faceModel.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
||||||
|
|
||||||
// Update audio trailing average for rendering facial animations
|
// Update audio trailing average for rendering facial animations
|
||||||
|
|
|
@ -79,6 +79,7 @@ void MyAvatar::reset() {
|
||||||
// TODO? resurrect headMouse stuff?
|
// TODO? resurrect headMouse stuff?
|
||||||
//_headMouseX = _glWidget->width() / 2;
|
//_headMouseX = _glWidget->width() / 2;
|
||||||
//_headMouseY = _glWidget->height() / 2;
|
//_headMouseY = _glWidget->height() / 2;
|
||||||
|
_skeletonModel.reset();
|
||||||
getHead()->reset();
|
getHead()->reset();
|
||||||
getHand()->reset();
|
getHand()->reset();
|
||||||
|
|
||||||
|
|
|
@ -1259,7 +1259,13 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
remainingModels.insert(model.key());
|
remainingModels.insert(model.key());
|
||||||
}
|
}
|
||||||
while (!remainingModels.isEmpty()) {
|
while (!remainingModels.isEmpty()) {
|
||||||
QString topID = getTopModelID(parentMap, models, *remainingModels.constBegin());
|
QString first = *remainingModels.constBegin();
|
||||||
|
foreach (const QString& id, remainingModels) {
|
||||||
|
if (id < first) {
|
||||||
|
first = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString topID = getTopModelID(parentMap, models, first);
|
||||||
appendModelIDs(parentMap.value(topID), childMap, models, remainingModels, modelIDs);
|
appendModelIDs(parentMap.value(topID), childMap, models, remainingModels, modelIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,9 +130,16 @@ void Model::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::reset() {
|
void Model::reset() {
|
||||||
|
if (_jointStates.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
foreach (Model* attachment, _attachments) {
|
foreach (Model* attachment, _attachments) {
|
||||||
attachment->reset();
|
attachment->reset();
|
||||||
}
|
}
|
||||||
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
|
for (int i = 0; i < _jointStates.size(); i++) {
|
||||||
|
_jointStates[i].rotation = geometry.joints.at(i).rotation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::clearShapes() {
|
void Model::clearShapes() {
|
||||||
|
|
|
@ -65,9 +65,15 @@ void MenuScriptingInterface::removeMenuItem(const QString& menu, const QString&
|
||||||
};
|
};
|
||||||
|
|
||||||
bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
|
bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
|
||||||
return Menu::getInstance()->isOptionChecked(menuOption);
|
bool result;
|
||||||
|
QMetaObject::invokeMethod(Menu::getInstance(), "isOptionChecked", Qt::BlockingQueuedConnection,
|
||||||
|
Q_RETURN_ARG(bool, result),
|
||||||
|
Q_ARG(const QString&, menuOption));
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuScriptingInterface::setIsOptionChecked(const QString& menuOption, bool isChecked) {
|
void MenuScriptingInterface::setIsOptionChecked(const QString& menuOption, bool isChecked) {
|
||||||
return Menu::getInstance()->setIsOptionChecked(menuOption, isChecked);
|
QMetaObject::invokeMethod(Menu::getInstance(), "setIsOptionChecked", Qt::BlockingQueuedConnection,
|
||||||
|
Q_ARG(const QString&, menuOption),
|
||||||
|
Q_ARG(bool, isChecked));
|
||||||
}
|
}
|
||||||
|
|
|
@ -506,8 +506,10 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
_perlinModulateProgram.setUniformValue("permutationNormalTexture", 0);
|
_perlinModulateProgram.setUniformValue("permutationNormalTexture", 0);
|
||||||
_perlinModulateProgram.release();
|
_perlinModulateProgram.release();
|
||||||
|
|
||||||
_shadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath()
|
_shadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||||
+ "shaders/shadow_map.frag");
|
Application::resourcesPath() + "shaders/shadow_map.vert");
|
||||||
|
_shadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||||
|
Application::resourcesPath() + "shaders/shadow_map.frag");
|
||||||
_shadowMapProgram.link();
|
_shadowMapProgram.link();
|
||||||
|
|
||||||
_shadowMapProgram.bind();
|
_shadowMapProgram.bind();
|
||||||
|
@ -1471,10 +1473,6 @@ void VoxelSystem::applyScaleAndBindProgram(bool texture) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Shadows)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Shadows)) {
|
||||||
_shadowMapProgram.bind();
|
_shadowMapProgram.bind();
|
||||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
||||||
glEnable(GL_TEXTURE_GEN_S);
|
|
||||||
glEnable(GL_TEXTURE_GEN_T);
|
|
||||||
glEnable(GL_TEXTURE_GEN_R);
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
glTexGenfv(GL_S, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[0]);
|
glTexGenfv(GL_S, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[0]);
|
||||||
glTexGenfv(GL_T, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[1]);
|
glTexGenfv(GL_T, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[1]);
|
||||||
|
@ -1496,10 +1494,7 @@ void VoxelSystem::removeScaleAndReleaseProgram(bool texture) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Shadows)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Shadows)) {
|
||||||
_shadowMapProgram.release();
|
_shadowMapProgram.release();
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glDisable(GL_TEXTURE_GEN_S);
|
|
||||||
glDisable(GL_TEXTURE_GEN_T);
|
|
||||||
glDisable(GL_TEXTURE_GEN_R);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
} else if (texture) {
|
} else if (texture) {
|
||||||
_perlinModulateProgram.release();
|
_perlinModulateProgram.release();
|
||||||
|
|
|
@ -29,6 +29,11 @@ quint64 OctreeElement::_externalChildrenMemoryUsage = 0;
|
||||||
quint64 OctreeElement::_voxelNodeCount = 0;
|
quint64 OctreeElement::_voxelNodeCount = 0;
|
||||||
quint64 OctreeElement::_voxelNodeLeafCount = 0;
|
quint64 OctreeElement::_voxelNodeLeafCount = 0;
|
||||||
|
|
||||||
|
void OctreeElement::resetPopulationStatistics() {
|
||||||
|
_voxelNodeCount = 0;
|
||||||
|
_voxelNodeLeafCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
OctreeElement::OctreeElement() {
|
OctreeElement::OctreeElement() {
|
||||||
// Note: you must call init() from your subclass, otherwise the OctreeElement will not be properly
|
// Note: you must call init() from your subclass, otherwise the OctreeElement will not be properly
|
||||||
// initialized. You will see DEADBEEF in your memory debugger if you have not properly called init()
|
// initialized. You will see DEADBEEF in your memory debugger if you have not properly called init()
|
||||||
|
|
|
@ -152,6 +152,7 @@ public:
|
||||||
static void addUpdateHook(OctreeElementUpdateHook* hook);
|
static void addUpdateHook(OctreeElementUpdateHook* hook);
|
||||||
static void removeUpdateHook(OctreeElementUpdateHook* hook);
|
static void removeUpdateHook(OctreeElementUpdateHook* hook);
|
||||||
|
|
||||||
|
static void resetPopulationStatistics();
|
||||||
static unsigned long getNodeCount() { return _voxelNodeCount; }
|
static unsigned long getNodeCount() { return _voxelNodeCount; }
|
||||||
static unsigned long getInternalNodeCount() { return _voxelNodeCount - _voxelNodeLeafCount; }
|
static unsigned long getInternalNodeCount() { return _voxelNodeCount - _voxelNodeLeafCount; }
|
||||||
static unsigned long getLeafNodeCount() { return _voxelNodeLeafCount; }
|
static unsigned long getLeafNodeCount() { return _voxelNodeLeafCount; }
|
||||||
|
|
|
@ -463,7 +463,6 @@ void ScriptEngine::timerFired() {
|
||||||
|
|
||||||
if (!callingTimer->isActive()) {
|
if (!callingTimer->isActive()) {
|
||||||
// this timer is done, we can kill it
|
// this timer is done, we can kill it
|
||||||
qDebug() << "Deleting a single shot timer";
|
|
||||||
delete callingTimer;
|
delete callingTimer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,18 +358,19 @@ int NodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedNodePointer NodeList::nodeWithUUID(const QUuid& nodeUUID, bool blockingLock) {
|
SharedNodePointer NodeList::nodeWithUUID(const QUuid& nodeUUID, bool blockingLock) {
|
||||||
|
const int WAIT_TIME = 10; // wait up to 10ms in the try lock case
|
||||||
SharedNodePointer node;
|
SharedNodePointer node;
|
||||||
// if caller wants us to block and guarantee the correct answer, then honor that request
|
// if caller wants us to block and guarantee the correct answer, then honor that request
|
||||||
if (blockingLock) {
|
if (blockingLock) {
|
||||||
// this will block till we can get access
|
// this will block till we can get access
|
||||||
QMutexLocker locker(&_nodeHashMutex);
|
QMutexLocker locker(&_nodeHashMutex);
|
||||||
node = _nodeHash.value(nodeUUID);
|
node = _nodeHash.value(nodeUUID);
|
||||||
} else if (_nodeHashMutex.tryLock()) { // some callers are willing to get wrong answers but not block
|
} else if (_nodeHashMutex.tryLock(WAIT_TIME)) { // some callers are willing to get wrong answers but not block
|
||||||
node = _nodeHash.value(nodeUUID);
|
node = _nodeHash.value(nodeUUID);
|
||||||
_nodeHashMutex.unlock();
|
_nodeHashMutex.unlock();
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedNodePointer NodeList::sendingNodeForPacket(const QByteArray& packet) {
|
SharedNodePointer NodeList::sendingNodeForPacket(const QByteArray& packet) {
|
||||||
QUuid nodeUUID = uuidFromPacketHeader(packet);
|
QUuid nodeUUID = uuidFromPacketHeader(packet);
|
||||||
|
|
|
@ -103,7 +103,6 @@ public:
|
||||||
QByteArray constructPingReplyPacket(const QByteArray& pingPacket);
|
QByteArray constructPingReplyPacket(const QByteArray& pingPacket);
|
||||||
void pingPublicAndLocalSocketsForInactiveNode(const SharedNodePointer& node);
|
void pingPublicAndLocalSocketsForInactiveNode(const SharedNodePointer& node);
|
||||||
|
|
||||||
/// passing false for blockingLock, will tryLock, and may return NULL when a node with the UUID actually does exist
|
|
||||||
SharedNodePointer nodeWithUUID(const QUuid& nodeUUID, bool blockingLock = true);
|
SharedNodePointer nodeWithUUID(const QUuid& nodeUUID, bool blockingLock = true);
|
||||||
SharedNodePointer sendingNodeForPacket(const QByteArray& packet);
|
SharedNodePointer sendingNodeForPacket(const QByteArray& packet);
|
||||||
|
|
||||||
|
|
|
@ -63,10 +63,12 @@ void ResourceCache::attemptRequest(Resource* resource) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_requestLimit--;
|
_requestLimit--;
|
||||||
|
_loadingRequests.append(resource);
|
||||||
resource->makeRequest();
|
resource->makeRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::requestCompleted() {
|
void ResourceCache::requestCompleted(Resource* resource) {
|
||||||
|
_loadingRequests.removeOne(resource);
|
||||||
_requestLimit++;
|
_requestLimit++;
|
||||||
|
|
||||||
// look for the highest priority pending request
|
// look for the highest priority pending request
|
||||||
|
@ -96,6 +98,7 @@ const int DEFAULT_REQUEST_LIMIT = 10;
|
||||||
int ResourceCache::_requestLimit = DEFAULT_REQUEST_LIMIT;
|
int ResourceCache::_requestLimit = DEFAULT_REQUEST_LIMIT;
|
||||||
|
|
||||||
QList<QPointer<Resource> > ResourceCache::_pendingRequests;
|
QList<QPointer<Resource> > ResourceCache::_pendingRequests;
|
||||||
|
QList<Resource*> ResourceCache::_loadingRequests;
|
||||||
|
|
||||||
Resource::Resource(const QUrl& url, bool delayLoad) :
|
Resource::Resource(const QUrl& url, bool delayLoad) :
|
||||||
_url(url),
|
_url(url),
|
||||||
|
@ -121,7 +124,7 @@ Resource::Resource(const QUrl& url, bool delayLoad) :
|
||||||
|
|
||||||
Resource::~Resource() {
|
Resource::~Resource() {
|
||||||
if (_reply) {
|
if (_reply) {
|
||||||
ResourceCache::requestCompleted();
|
ResourceCache::requestCompleted(this);
|
||||||
delete _reply;
|
delete _reply;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,7 +218,7 @@ void Resource::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
|
||||||
_replyTimer->disconnect(this);
|
_replyTimer->disconnect(this);
|
||||||
_replyTimer->deleteLater();
|
_replyTimer->deleteLater();
|
||||||
_replyTimer = NULL;
|
_replyTimer = NULL;
|
||||||
ResourceCache::requestCompleted();
|
ResourceCache::requestCompleted(this);
|
||||||
|
|
||||||
downloadFinished(reply);
|
downloadFinished(reply);
|
||||||
}
|
}
|
||||||
|
@ -250,7 +253,7 @@ void Resource::handleReplyError(QNetworkReply::NetworkError error, QDebug debug)
|
||||||
_replyTimer->disconnect(this);
|
_replyTimer->disconnect(this);
|
||||||
_replyTimer->deleteLater();
|
_replyTimer->deleteLater();
|
||||||
_replyTimer = NULL;
|
_replyTimer = NULL;
|
||||||
ResourceCache::requestCompleted();
|
ResourceCache::requestCompleted(this);
|
||||||
|
|
||||||
// retry for certain types of failures
|
// retry for certain types of failures
|
||||||
switch (error) {
|
switch (error) {
|
||||||
|
|
|
@ -37,6 +37,10 @@ public:
|
||||||
static void setRequestLimit(int limit) { _requestLimit = limit; }
|
static void setRequestLimit(int limit) { _requestLimit = limit; }
|
||||||
static int getRequestLimit() { return _requestLimit; }
|
static int getRequestLimit() { return _requestLimit; }
|
||||||
|
|
||||||
|
static const QList<Resource*>& getLoadingRequests() { return _loadingRequests; }
|
||||||
|
|
||||||
|
static int getPendingRequestCount() { return _pendingRequests.size(); }
|
||||||
|
|
||||||
ResourceCache(QObject* parent = NULL);
|
ResourceCache(QObject* parent = NULL);
|
||||||
virtual ~ResourceCache();
|
virtual ~ResourceCache();
|
||||||
|
|
||||||
|
@ -58,7 +62,7 @@ protected:
|
||||||
void addUnusedResource(const QSharedPointer<Resource>& resource);
|
void addUnusedResource(const QSharedPointer<Resource>& resource);
|
||||||
|
|
||||||
static void attemptRequest(Resource* resource);
|
static void attemptRequest(Resource* resource);
|
||||||
static void requestCompleted();
|
static void requestCompleted(Resource* resource);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -70,6 +74,7 @@ private:
|
||||||
static QNetworkAccessManager* _networkAccessManager;
|
static QNetworkAccessManager* _networkAccessManager;
|
||||||
static int _requestLimit;
|
static int _requestLimit;
|
||||||
static QList<QPointer<Resource> > _pendingRequests;
|
static QList<QPointer<Resource> > _pendingRequests;
|
||||||
|
static QList<Resource*> _loadingRequests;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for resources.
|
/// Base class for resources.
|
||||||
|
@ -102,6 +107,15 @@ public:
|
||||||
/// Checks whether the resource has loaded.
|
/// Checks whether the resource has loaded.
|
||||||
bool isLoaded() const { return _loaded; }
|
bool isLoaded() const { return _loaded; }
|
||||||
|
|
||||||
|
/// For loading resources, returns the number of bytes received.
|
||||||
|
qint64 getBytesReceived() const { return _bytesReceived; }
|
||||||
|
|
||||||
|
/// For loading resources, returns the number of total bytes (or zero if unknown).
|
||||||
|
qint64 getBytesTotal() const { return _bytesTotal; }
|
||||||
|
|
||||||
|
/// For loading resources, returns the load progress.
|
||||||
|
float getProgress() const { return (_bytesTotal == 0) ? 0.0f : (float)_bytesReceived / _bytesTotal; }
|
||||||
|
|
||||||
void setSelf(const QWeakPointer<Resource>& self) { _self = self; }
|
void setSelf(const QWeakPointer<Resource>& self) { _self = self; }
|
||||||
|
|
||||||
void setCache(ResourceCache* cache) { _cache = cache; }
|
void setCache(ResourceCache* cache) { _cache = cache; }
|
||||||
|
@ -152,6 +166,7 @@ private:
|
||||||
int _lruKey;
|
int _lruKey;
|
||||||
QNetworkReply* _reply;
|
QNetworkReply* _reply;
|
||||||
QTimer* _replyTimer;
|
QTimer* _replyTimer;
|
||||||
|
int _index;
|
||||||
qint64 _bytesReceived;
|
qint64 _bytesReceived;
|
||||||
qint64 _bytesTotal;
|
qint64 _bytesTotal;
|
||||||
int _attempts;
|
int _attempts;
|
||||||
|
|
Loading…
Reference in a new issue