mirror of
https://github.com/lubosz/overte.git
synced 2025-08-08 02:48:12 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into 19495
This commit is contained in:
commit
cd1ec97d28
40 changed files with 801 additions and 247 deletions
|
@ -13,6 +13,7 @@
|
||||||
#include <QtNetwork/QNetworkRequest>
|
#include <QtNetwork/QNetworkRequest>
|
||||||
#include <QtNetwork/QNetworkReply>
|
#include <QtNetwork/QNetworkReply>
|
||||||
|
|
||||||
|
#include <AudioRingBuffer.h>
|
||||||
#include <AvatarData.h>
|
#include <AvatarData.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
|
@ -25,7 +26,8 @@
|
||||||
Agent::Agent(const QByteArray& packet) :
|
Agent::Agent(const QByteArray& packet) :
|
||||||
ThreadedAssignment(packet),
|
ThreadedAssignment(packet),
|
||||||
_voxelEditSender(),
|
_voxelEditSender(),
|
||||||
_particleEditSender()
|
_particleEditSender(),
|
||||||
|
_avatarAudioStream(NULL)
|
||||||
{
|
{
|
||||||
// be the parent of the script engine so it gets moved when we do
|
// be the parent of the script engine so it gets moved when we do
|
||||||
_scriptEngine.setParent(this);
|
_scriptEngine.setParent(this);
|
||||||
|
@ -34,6 +36,30 @@ Agent::Agent(const QByteArray& packet) :
|
||||||
_scriptEngine.getParticlesScriptingInterface()->setPacketSender(&_particleEditSender);
|
_scriptEngine.getParticlesScriptingInterface()->setPacketSender(&_particleEditSender);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Agent::~Agent() {
|
||||||
|
delete _avatarAudioStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int SCRIPT_AUDIO_BUFFER_SAMPLES = floor(((SCRIPT_DATA_CALLBACK_USECS * SAMPLE_RATE) / (1000 * 1000)) + 0.5);
|
||||||
|
|
||||||
|
void Agent::setSendAvatarAudioStream(bool sendAvatarAudioStream) {
|
||||||
|
if (sendAvatarAudioStream) {
|
||||||
|
// the agentAudioStream number of samples is related to the ScriptEngine callback rate
|
||||||
|
_avatarAudioStream = new int16_t[SCRIPT_AUDIO_BUFFER_SAMPLES];
|
||||||
|
|
||||||
|
// fill the _audioStream with zeroes to start
|
||||||
|
memset(_avatarAudioStream, 0, SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t));
|
||||||
|
|
||||||
|
_scriptEngine.setNumAvatarAudioBufferSamples(SCRIPT_AUDIO_BUFFER_SAMPLES);
|
||||||
|
_scriptEngine.setAvatarAudioBuffer(_avatarAudioStream);
|
||||||
|
} else {
|
||||||
|
delete _avatarAudioStream;
|
||||||
|
_avatarAudioStream = NULL;
|
||||||
|
|
||||||
|
_scriptEngine.setAvatarAudioBuffer(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Agent::readPendingDatagrams() {
|
void Agent::readPendingDatagrams() {
|
||||||
QByteArray receivedPacket;
|
QByteArray receivedPacket;
|
||||||
HifiSockAddr senderSockAddr;
|
HifiSockAddr senderSockAddr;
|
||||||
|
|
|
@ -28,12 +28,17 @@ class Agent : public ThreadedAssignment {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(bool isAvatar READ isAvatar WRITE setIsAvatar)
|
Q_PROPERTY(bool isAvatar READ isAvatar WRITE setIsAvatar)
|
||||||
|
Q_PROPERTY(bool sendAvatarAudioStream READ isSendingAvatarAudioStream WRITE setSendAvatarAudioStream)
|
||||||
public:
|
public:
|
||||||
Agent(const QByteArray& packet);
|
Agent(const QByteArray& packet);
|
||||||
|
~Agent();
|
||||||
|
|
||||||
void setIsAvatar(bool isAvatar) { QMetaObject::invokeMethod(&_scriptEngine, "setIsAvatar", Q_ARG(bool, isAvatar)); }
|
void setIsAvatar(bool isAvatar) { QMetaObject::invokeMethod(&_scriptEngine, "setIsAvatar", Q_ARG(bool, isAvatar)); }
|
||||||
bool isAvatar() const { return _scriptEngine.isAvatar(); }
|
bool isAvatar() const { return _scriptEngine.isAvatar(); }
|
||||||
|
|
||||||
|
void setSendAvatarAudioStream(bool sendAvatarAudioStream);
|
||||||
|
bool isSendingAvatarAudioStream() const { return (bool) _scriptEngine.sendsAvatarAudioStream(); }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void run();
|
void run();
|
||||||
void readPendingDatagrams();
|
void readPendingDatagrams();
|
||||||
|
@ -45,6 +50,8 @@ private:
|
||||||
|
|
||||||
ParticleTreeHeadlessViewer _particleViewer;
|
ParticleTreeHeadlessViewer _particleViewer;
|
||||||
VoxelTreeHeadlessViewer _voxelViewer;
|
VoxelTreeHeadlessViewer _voxelViewer;
|
||||||
|
|
||||||
|
int16_t* _avatarAudioStream;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__Agent__) */
|
#endif /* defined(__hifi__Agent__) */
|
||||||
|
|
|
@ -241,6 +241,9 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue
|
||||||
int truePacketsSent = 0;
|
int truePacketsSent = 0;
|
||||||
int trueBytesSent = 0;
|
int trueBytesSent = 0;
|
||||||
int packetsSentThisInterval = 0;
|
int packetsSentThisInterval = 0;
|
||||||
|
bool isFullScene = ((!viewFrustumChanged || !nodeData->getWantDelta()) && nodeData->getViewFrustumJustStoppedChanging())
|
||||||
|
|| nodeData->hasLodChanged();
|
||||||
|
|
||||||
bool somethingToSend = true; // assume we have something
|
bool somethingToSend = true; // assume we have something
|
||||||
|
|
||||||
// FOR NOW... node tells us if it wants to receive only view frustum deltas
|
// FOR NOW... node tells us if it wants to receive only view frustum deltas
|
||||||
|
@ -365,10 +368,6 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue
|
||||||
<< " Wasted:" << _totalWastedBytes;
|
<< " Wasted:" << _totalWastedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start tracking our stats
|
|
||||||
bool isFullScene = ((!viewFrustumChanged || !nodeData->getWantDelta())
|
|
||||||
&& nodeData->getViewFrustumJustStoppedChanging()) || nodeData->hasLodChanged();
|
|
||||||
|
|
||||||
// If we're starting a full scene, then definitely we want to empty the nodeBag
|
// If we're starting a full scene, then definitely we want to empty the nodeBag
|
||||||
if (isFullScene) {
|
if (isFullScene) {
|
||||||
nodeData->nodeBag.deleteAll();
|
nodeData->nodeBag.deleteAll();
|
||||||
|
@ -382,6 +381,7 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue
|
||||||
}
|
}
|
||||||
|
|
||||||
::startSceneSleepTime = _usleepTime;
|
::startSceneSleepTime = _usleepTime;
|
||||||
|
// start tracking our stats
|
||||||
nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged, _myServer->getOctree()->getRoot(), _myServer->getJurisdiction());
|
nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged, _myServer->getOctree()->getRoot(), _myServer->getJurisdiction());
|
||||||
|
|
||||||
// This is the start of "resending" the scene.
|
// This is the start of "resending" the scene.
|
||||||
|
@ -432,10 +432,6 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue
|
||||||
int boundaryLevelAdjust = boundaryLevelAdjustClient + (viewFrustumChanged && nodeData->getWantLowResMoving()
|
int boundaryLevelAdjust = boundaryLevelAdjustClient + (viewFrustumChanged && nodeData->getWantLowResMoving()
|
||||||
? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST);
|
? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST);
|
||||||
|
|
||||||
|
|
||||||
bool isFullScene = ((!viewFrustumChanged || !nodeData->getWantDelta()) &&
|
|
||||||
nodeData->getViewFrustumJustStoppedChanging()) || nodeData->hasLodChanged();
|
|
||||||
|
|
||||||
EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(), wantColor,
|
EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(), wantColor,
|
||||||
WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum,
|
WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum,
|
||||||
wantOcclusionCulling, coverageMap, boundaryLevelAdjust, voxelSizeScale,
|
wantOcclusionCulling, coverageMap, boundaryLevelAdjust, voxelSizeScale,
|
||||||
|
|
|
@ -544,8 +544,16 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
// construct the requested assignment from the packet data
|
// construct the requested assignment from the packet data
|
||||||
Assignment requestAssignment(receivedPacket);
|
Assignment requestAssignment(receivedPacket);
|
||||||
|
|
||||||
qDebug() << "Received a request for assignment type" << requestAssignment.getType()
|
// Suppress these for Assignment::AgentType to once per 5 seconds
|
||||||
<< "from" << senderSockAddr;
|
static quint64 lastNoisyMessage = usecTimestampNow();
|
||||||
|
quint64 timeNow = usecTimestampNow();
|
||||||
|
const quint64 NOISY_TIME_ELAPSED = 5 * USECS_PER_SECOND;
|
||||||
|
bool noisyMessage = false;
|
||||||
|
if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastNoisyMessage) > NOISY_TIME_ELAPSED) {
|
||||||
|
qDebug() << "Received a request for assignment type" << requestAssignment.getType()
|
||||||
|
<< "from" << senderSockAddr;
|
||||||
|
noisyMessage = true;
|
||||||
|
}
|
||||||
|
|
||||||
SharedAssignmentPointer assignmentToDeploy = deployableAssignmentForRequest(requestAssignment);
|
SharedAssignmentPointer assignmentToDeploy = deployableAssignmentForRequest(requestAssignment);
|
||||||
|
|
||||||
|
@ -562,8 +570,15 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
nodeList->getNodeSocket().writeDatagram(assignmentPacket,
|
nodeList->getNodeSocket().writeDatagram(assignmentPacket,
|
||||||
senderSockAddr.getAddress(), senderSockAddr.getPort());
|
senderSockAddr.getAddress(), senderSockAddr.getPort());
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType()
|
if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastNoisyMessage) > NOISY_TIME_ELAPSED) {
|
||||||
<< "from" << senderSockAddr;
|
qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType()
|
||||||
|
<< "from" << senderSockAddr;
|
||||||
|
noisyMessage = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noisyMessage) {
|
||||||
|
lastNoisyMessage = timeNow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,10 @@ var PIXELS_PER_EXTRUDE_VOXEL = 16;
|
||||||
var WHEEL_PIXELS_PER_SCALE_CHANGE = 100;
|
var WHEEL_PIXELS_PER_SCALE_CHANGE = 100;
|
||||||
var MAX_VOXEL_SCALE = 1.0;
|
var MAX_VOXEL_SCALE = 1.0;
|
||||||
var MIN_VOXEL_SCALE = 1.0 / Math.pow(2.0, 8.0);
|
var MIN_VOXEL_SCALE = 1.0 / Math.pow(2.0, 8.0);
|
||||||
|
var WHITE_COLOR = { red: 255, green: 255, blue: 255 };
|
||||||
|
|
||||||
|
var MAX_PASTE_VOXEL_SCALE = 256;
|
||||||
|
var MIN_PASTE_VOXEL_SCALE = .256;
|
||||||
|
|
||||||
var zFightingSizeAdjust = 0.002; // used to adjust preview voxels to prevent z fighting
|
var zFightingSizeAdjust = 0.002; // used to adjust preview voxels to prevent z fighting
|
||||||
var previewLineWidth = 1.5;
|
var previewLineWidth = 1.5;
|
||||||
|
@ -199,6 +203,8 @@ var voxelToolAt = 0;
|
||||||
var recolorToolAt = 1;
|
var recolorToolAt = 1;
|
||||||
var eyedropperToolAt = 2;
|
var eyedropperToolAt = 2;
|
||||||
|
|
||||||
|
var pasteModeColor = { red: 132, green: 61, blue: 255 };
|
||||||
|
|
||||||
var voxelTool = Overlays.addOverlay("image", {
|
var voxelTool = Overlays.addOverlay("image", {
|
||||||
x: 0, y: 0, width: toolWidth, height: toolHeight,
|
x: 0, y: 0, width: toolWidth, height: toolHeight,
|
||||||
subImage: { x: 0, y: toolHeight, width: toolWidth, height: toolHeight },
|
subImage: { x: 0, y: toolHeight, width: toolWidth, height: toolHeight },
|
||||||
|
@ -262,7 +268,7 @@ var thumb = Overlays.addOverlay("image", {
|
||||||
visible: false
|
visible: false
|
||||||
});
|
});
|
||||||
|
|
||||||
var pointerVoxelScale = 0; // this is the voxel scale used for click to add or delete
|
var pointerVoxelScale = Math.floor(MAX_VOXEL_SCALE + MIN_VOXEL_SCALE) / 2; // this is the voxel scale used for click to add or delete
|
||||||
var pointerVoxelScaleSet = false; // if voxel scale has not yet been set, we use the intersection size
|
var pointerVoxelScaleSet = false; // if voxel scale has not yet been set, we use the intersection size
|
||||||
|
|
||||||
var pointerVoxelScaleSteps = 8; // the number of slider position steps
|
var pointerVoxelScaleSteps = 8; // the number of slider position steps
|
||||||
|
@ -271,6 +277,106 @@ var pointerVoxelScaleMin = Math.pow(2, (1-pointerVoxelScaleOriginStep));
|
||||||
var pointerVoxelScaleMax = Math.pow(2, (pointerVoxelScaleSteps-pointerVoxelScaleOriginStep));
|
var pointerVoxelScaleMax = Math.pow(2, (pointerVoxelScaleSteps-pointerVoxelScaleOriginStep));
|
||||||
var thumbDeltaPerStep = thumbExtents / (pointerVoxelScaleSteps - 1);
|
var thumbDeltaPerStep = thumbExtents / (pointerVoxelScaleSteps - 1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////// IMPORT MODULE ///////////////////////////////
|
||||||
|
// Move the following code to a separate file when include will be available.
|
||||||
|
var importTree;
|
||||||
|
var importPreview;
|
||||||
|
var importBoundaries;
|
||||||
|
var isImporting;
|
||||||
|
var importPosition;
|
||||||
|
var importScale;
|
||||||
|
|
||||||
|
function initImport() {
|
||||||
|
importPreview = Overlays.addOverlay("localvoxels", {
|
||||||
|
name: "import",
|
||||||
|
position: { x: 0, y: 0, z: 0},
|
||||||
|
scale: 1,
|
||||||
|
visible: false
|
||||||
|
});
|
||||||
|
importBoundaries = Overlays.addOverlay("cube", {
|
||||||
|
position: { x: 0, y: 0, z: 0 },
|
||||||
|
scale: 1,
|
||||||
|
color: { red: 128, blue: 128, green: 128 },
|
||||||
|
solid: false,
|
||||||
|
visible: false
|
||||||
|
})
|
||||||
|
isImporting = false;
|
||||||
|
importPosition = { x: 0, y: 0, z: 0 };
|
||||||
|
importScale = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function importVoxels() {
|
||||||
|
if (Clipboard.importVoxels()) {
|
||||||
|
isImporting = true;
|
||||||
|
if (importScale <= 0) {
|
||||||
|
importScale = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isImporting = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isImporting;
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveImport(position) {
|
||||||
|
if (0 < position.x && 0 < position.y && 0 < position.z) {
|
||||||
|
importPosition = position;
|
||||||
|
Overlays.editOverlay(importPreview, {
|
||||||
|
position: { x: importPosition.x, y: importPosition.y, z: importPosition.z }
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(importBoundaries, {
|
||||||
|
position: { x: importPosition.x, y: importPosition.y, z: importPosition.z }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function rescaleImport(scale) {
|
||||||
|
if (0 < scale) {
|
||||||
|
importScale = scale;
|
||||||
|
Overlays.editOverlay(importPreview, {
|
||||||
|
scale: importScale
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(importBoundaries, {
|
||||||
|
scale: importScale
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showImport(doShow) {
|
||||||
|
Overlays.editOverlay(importPreview, {
|
||||||
|
visible: doShow
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(importBoundaries, {
|
||||||
|
visible: doShow
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function placeImport() {
|
||||||
|
if (isImporting) {
|
||||||
|
Clipboard.pasteVoxel(importPosition.x, importPosition.y, importPosition.z, importScale);
|
||||||
|
isImporting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelImport() {
|
||||||
|
if (isImporting) {
|
||||||
|
isImporting = false;
|
||||||
|
showImport(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanupImport() {
|
||||||
|
Overlays.deleteOverlay(importPreview);
|
||||||
|
Overlays.deleteOverlay(importBoundaries);
|
||||||
|
isImporting = false;
|
||||||
|
importPostion = { x: 0, y: 0, z: 0 };
|
||||||
|
importScale = 0;
|
||||||
|
}
|
||||||
|
/////////////////////////////////// END IMPORT MODULE /////////////////////////////
|
||||||
|
initImport();
|
||||||
|
|
||||||
if (editToolsOn) {
|
if (editToolsOn) {
|
||||||
moveTools();
|
moveTools();
|
||||||
}
|
}
|
||||||
|
@ -295,6 +401,13 @@ function calcScaleFromThumb(newThumbX) {
|
||||||
thumbAt = newThumbX - minThumbX;
|
thumbAt = newThumbX - minThumbX;
|
||||||
thumbStep = Math.floor((thumbAt/ thumbExtents) * (pointerVoxelScaleSteps-1)) + 1;
|
thumbStep = Math.floor((thumbAt/ thumbExtents) * (pointerVoxelScaleSteps-1)) + 1;
|
||||||
pointerVoxelScale = Math.pow(2, (thumbStep-pointerVoxelScaleOriginStep));
|
pointerVoxelScale = Math.pow(2, (thumbStep-pointerVoxelScaleOriginStep));
|
||||||
|
|
||||||
|
// if importing, rescale import ...
|
||||||
|
if (isImporting) {
|
||||||
|
var importScale = (pointerVoxelScale / MAX_VOXEL_SCALE) * MAX_PASTE_VOXEL_SCALE;
|
||||||
|
rescaleImport(importScale);
|
||||||
|
}
|
||||||
|
|
||||||
// now reset the display accordingly...
|
// now reset the display accordingly...
|
||||||
calcThumbFromScale(pointerVoxelScale);
|
calcThumbFromScale(pointerVoxelScale);
|
||||||
|
|
||||||
|
@ -308,7 +421,23 @@ function setAudioPosition() {
|
||||||
audioOptions.position = Vec3.sum(camera, forwardVector);
|
audioOptions.position = Vec3.sum(camera, forwardVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNewVoxelPosition() {
|
function getNewPasteVoxel(pickRay) {
|
||||||
|
|
||||||
|
var voxelSize = MIN_PASTE_VOXEL_SCALE + (MAX_PASTE_VOXEL_SCALE - MIN_PASTE_VOXEL_SCALE) * pointerVoxelScale - 1;
|
||||||
|
var origin = { x: pickRay.direction.x, y: pickRay.direction.y, z: pickRay.direction.z };
|
||||||
|
|
||||||
|
origin.x += pickRay.origin.x;
|
||||||
|
origin.y += pickRay.origin.y;
|
||||||
|
origin.z += pickRay.origin.z;
|
||||||
|
|
||||||
|
origin.x -= voxelSize / 2;
|
||||||
|
origin.y -= voxelSize / 2;
|
||||||
|
origin.z += voxelSize / 2;
|
||||||
|
|
||||||
|
return {origin: origin, voxelSize: voxelSize};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNewVoxelPosition() {
|
||||||
var camera = Camera.getPosition();
|
var camera = Camera.getPosition();
|
||||||
var forwardVector = Quat.getFront(MyAvatar.orientation);
|
var forwardVector = Quat.getFront(MyAvatar.orientation);
|
||||||
var newPosition = Vec3.sum(camera, Vec3.multiply(forwardVector, NEW_VOXEL_DISTANCE_FROM_CAMERA));
|
var newPosition = Vec3.sum(camera, Vec3.multiply(forwardVector, NEW_VOXEL_DISTANCE_FROM_CAMERA));
|
||||||
|
@ -337,6 +466,7 @@ var trackAsOrbitOrPan = false;
|
||||||
var voxelToolSelected = true;
|
var voxelToolSelected = true;
|
||||||
var recolorToolSelected = false;
|
var recolorToolSelected = false;
|
||||||
var eyedropperToolSelected = false;
|
var eyedropperToolSelected = false;
|
||||||
|
var pasteMode = false;
|
||||||
|
|
||||||
function playRandomAddSound(audioOptions) {
|
function playRandomAddSound(audioOptions) {
|
||||||
if (Math.random() < 0.33) {
|
if (Math.random() < 0.33) {
|
||||||
|
@ -523,6 +653,38 @@ function showPreviewVoxel() {
|
||||||
function showPreviewLines() {
|
function showPreviewLines() {
|
||||||
|
|
||||||
var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY);
|
var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY);
|
||||||
|
|
||||||
|
if (pasteMode) { // free voxel pasting
|
||||||
|
|
||||||
|
Overlays.editOverlay(voxelPreview, { visible: false });
|
||||||
|
Overlays.editOverlay(linePreviewLeft, { visible: false });
|
||||||
|
|
||||||
|
var pasteVoxel = getNewPasteVoxel(pickRay);
|
||||||
|
|
||||||
|
// X axis
|
||||||
|
Overlays.editOverlay(linePreviewBottom, {
|
||||||
|
position: pasteVoxel.origin,
|
||||||
|
end: {x: pasteVoxel.origin.x + pasteVoxel.voxelSize, y: pasteVoxel.origin.y, z: pasteVoxel.origin.z },
|
||||||
|
visible: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Y axis
|
||||||
|
Overlays.editOverlay(linePreviewRight, {
|
||||||
|
position: pasteVoxel.origin,
|
||||||
|
end: {x: pasteVoxel.origin.x, y: pasteVoxel.origin.y + pasteVoxel.voxelSize, z: pasteVoxel.origin.z },
|
||||||
|
visible: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Z axis
|
||||||
|
Overlays.editOverlay(linePreviewTop, {
|
||||||
|
position: pasteVoxel.origin,
|
||||||
|
end: {x: pasteVoxel.origin.x, y: pasteVoxel.origin.y, z: pasteVoxel.origin.z - pasteVoxel.voxelSize },
|
||||||
|
visible: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var intersection = Voxels.findRayIntersection(pickRay);
|
var intersection = Voxels.findRayIntersection(pickRay);
|
||||||
|
|
||||||
if (intersection.intersects) {
|
if (intersection.intersects) {
|
||||||
|
@ -617,6 +779,8 @@ function trackKeyReleaseEvent(event) {
|
||||||
if (editToolsOn) {
|
if (editToolsOn) {
|
||||||
if (event.text == "ESC") {
|
if (event.text == "ESC") {
|
||||||
pointerVoxelScaleSet = false;
|
pointerVoxelScaleSet = false;
|
||||||
|
pasteMode = false;
|
||||||
|
moveTools();
|
||||||
}
|
}
|
||||||
if (event.text == "-") {
|
if (event.text == "-") {
|
||||||
thumbX -= thumbDeltaPerStep;
|
thumbX -= thumbDeltaPerStep;
|
||||||
|
@ -821,6 +985,23 @@ function mousePressEvent(event) {
|
||||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
var intersection = Voxels.findRayIntersection(pickRay);
|
var intersection = Voxels.findRayIntersection(pickRay);
|
||||||
audioOptions.position = Vec3.sum(pickRay.origin, pickRay.direction);
|
audioOptions.position = Vec3.sum(pickRay.origin, pickRay.direction);
|
||||||
|
|
||||||
|
if (isImporting) {
|
||||||
|
print("placing import...");
|
||||||
|
placeImport();
|
||||||
|
showImport(false);
|
||||||
|
moveTools();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pasteMode) {
|
||||||
|
var pasteVoxel = getNewPasteVoxel(pickRay);
|
||||||
|
Clipboard.pasteVoxel(pasteVoxel.origin.x, pasteVoxel.origin.y, pasteVoxel.origin.z, pasteVoxel.voxelSize);
|
||||||
|
pasteMode = false;
|
||||||
|
moveTools();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (intersection.intersects) {
|
if (intersection.intersects) {
|
||||||
// if the user hasn't updated the
|
// if the user hasn't updated the
|
||||||
if (!pointerVoxelScaleSet) {
|
if (!pointerVoxelScaleSet) {
|
||||||
|
@ -967,25 +1148,42 @@ function cleanupMenus() {
|
||||||
function menuItemEvent(menuItem) {
|
function menuItemEvent(menuItem) {
|
||||||
|
|
||||||
// handle clipboard items
|
// handle clipboard items
|
||||||
if (selectToolSelected) {
|
if (editToolsOn) {
|
||||||
|
|
||||||
var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY);
|
var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY);
|
||||||
var intersection = Voxels.findRayIntersection(pickRay);
|
var intersection = Voxels.findRayIntersection(pickRay);
|
||||||
selectedVoxel = calculateVoxelFromIntersection(intersection,"select");
|
selectedVoxel = calculateVoxelFromIntersection(intersection,"select");
|
||||||
if (menuItem == "Copy") {
|
if (menuItem == "Copy") {
|
||||||
print("copying...");
|
print("copying...");
|
||||||
Clipboard.copyVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
|
Clipboard.copyVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
|
||||||
|
pasteMode = true;
|
||||||
|
moveTools();
|
||||||
}
|
}
|
||||||
if (menuItem == "Cut") {
|
if (menuItem == "Cut") {
|
||||||
print("cutting...");
|
print("cutting...");
|
||||||
Clipboard.cutVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
|
Clipboard.cutVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
|
||||||
|
pasteMode = true;
|
||||||
|
moveTools();
|
||||||
}
|
}
|
||||||
if (menuItem == "Paste") {
|
if (menuItem == "Paste") {
|
||||||
print("pasting...");
|
if (isImporting) {
|
||||||
Clipboard.pasteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
|
print("placing import...");
|
||||||
|
placeImport();
|
||||||
|
showImport(false);
|
||||||
|
} else {
|
||||||
|
print("pasting...");
|
||||||
|
Clipboard.pasteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
|
||||||
|
}
|
||||||
|
pasteMode = false;
|
||||||
|
moveTools();
|
||||||
}
|
}
|
||||||
if (menuItem == "Delete") {
|
if (menuItem == "Delete") {
|
||||||
print("deleting...");
|
print("deleting...");
|
||||||
Clipboard.deleteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
|
if (isImporting) {
|
||||||
|
cancelImport();
|
||||||
|
} else {
|
||||||
|
Clipboard.deleteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menuItem == "Export Voxels") {
|
if (menuItem == "Export Voxels") {
|
||||||
|
@ -993,8 +1191,11 @@ function menuItemEvent(menuItem) {
|
||||||
Clipboard.exportVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
|
Clipboard.exportVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
|
||||||
}
|
}
|
||||||
if (menuItem == "Import Voxels") {
|
if (menuItem == "Import Voxels") {
|
||||||
print("import");
|
print("importing...");
|
||||||
Clipboard.importVoxels();
|
if (importVoxels()) {
|
||||||
|
showImport(true);
|
||||||
|
}
|
||||||
|
moveTools();
|
||||||
}
|
}
|
||||||
if (menuItem == "Nudge") {
|
if (menuItem == "Nudge") {
|
||||||
print("nudge");
|
print("nudge");
|
||||||
|
@ -1149,19 +1350,23 @@ function moveTools() {
|
||||||
recolorToolOffset = 1,
|
recolorToolOffset = 1,
|
||||||
eyedropperToolOffset = 1;
|
eyedropperToolOffset = 1;
|
||||||
|
|
||||||
if (trackAsRecolor || recolorToolSelected) {
|
var voxelToolColor = WHITE_COLOR;
|
||||||
|
|
||||||
|
if (recolorToolSelected) {
|
||||||
recolorToolOffset = 2;
|
recolorToolOffset = 2;
|
||||||
} else if (trackAsEyedropper || eyedropperToolSelected) {
|
} else if (eyedropperToolSelected) {
|
||||||
eyedropperToolOffset = 2;
|
eyedropperToolOffset = 2;
|
||||||
} else if (trackAsOrbitOrPan) {
|
|
||||||
// nothing gets selected in this case...
|
|
||||||
} else {
|
} else {
|
||||||
|
if (pasteMode) {
|
||||||
|
voxelToolColor = pasteModeColor;
|
||||||
|
}
|
||||||
voxelToolOffset = 2;
|
voxelToolOffset = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Overlays.editOverlay(voxelTool, {
|
Overlays.editOverlay(voxelTool, {
|
||||||
subImage: { x: 0, y: toolHeight * voxelToolOffset, width: toolWidth, height: toolHeight },
|
subImage: { x: 0, y: toolHeight * voxelToolOffset, width: toolWidth, height: toolHeight },
|
||||||
x: toolsX, y: toolsY + ((toolHeight + toolVerticalSpacing) * voxelToolAt), width: toolWidth, height: toolHeight,
|
x: toolsX, y: toolsY + ((toolHeight + toolVerticalSpacing) * voxelToolAt), width: toolWidth, height: toolHeight,
|
||||||
|
color: voxelToolColor,
|
||||||
visible: editToolsOn
|
visible: editToolsOn
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1323,14 +1528,27 @@ function checkControllers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function update(deltaTime) {
|
function update(deltaTime) {
|
||||||
var newWindowDimensions = Controller.getViewportDimensions();
|
|
||||||
if (newWindowDimensions.x != windowDimensions.x || newWindowDimensions.y != windowDimensions.y) {
|
|
||||||
windowDimensions = newWindowDimensions;
|
|
||||||
moveTools();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (editToolsOn) {
|
if (editToolsOn) {
|
||||||
|
var newWindowDimensions = Controller.getViewportDimensions();
|
||||||
|
if (newWindowDimensions.x != windowDimensions.x || newWindowDimensions.y != windowDimensions.y) {
|
||||||
|
windowDimensions = newWindowDimensions;
|
||||||
|
moveTools();
|
||||||
|
}
|
||||||
|
|
||||||
checkControllers();
|
checkControllers();
|
||||||
|
|
||||||
|
// Move Import Preview
|
||||||
|
if (isImporting) {
|
||||||
|
var position = MyAvatar.position;
|
||||||
|
var forwardVector = Quat.getFront(MyAvatar.orientation);
|
||||||
|
var targetPosition = Vec3.sum(position, Vec3.multiply(forwardVector, importScale));
|
||||||
|
var newPosition = {
|
||||||
|
x: Math.floor(targetPosition.x / importScale) * importScale,
|
||||||
|
y: Math.floor(targetPosition.y / importScale) * importScale,
|
||||||
|
z: Math.floor(targetPosition.z / importScale) * importScale
|
||||||
|
}
|
||||||
|
moveImport(newPosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1356,6 +1574,11 @@ function wheelEvent(event) {
|
||||||
calcThumbFromScale(pointerVoxelScale);
|
calcThumbFromScale(pointerVoxelScale);
|
||||||
trackMouseEvent(event);
|
trackMouseEvent(event);
|
||||||
wheelPixelsMoved = 0;
|
wheelPixelsMoved = 0;
|
||||||
|
|
||||||
|
if (isImporting) {
|
||||||
|
var importScale = (pointerVoxelScale / MAX_VOXEL_SCALE) * MAX_PASTE_VOXEL_SCALE;
|
||||||
|
rescaleImport(importScale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1388,6 +1611,7 @@ function scriptEnding() {
|
||||||
Overlays.deleteOverlay(thumb);
|
Overlays.deleteOverlay(thumb);
|
||||||
Controller.releaseKeyEvents({ text: "+" });
|
Controller.releaseKeyEvents({ text: "+" });
|
||||||
Controller.releaseKeyEvents({ text: "-" });
|
Controller.releaseKeyEvents({ text: "-" });
|
||||||
|
cleanupImport();
|
||||||
cleanupMenus();
|
cleanupMenus();
|
||||||
}
|
}
|
||||||
Script.scriptEnding.connect(scriptEnding);
|
Script.scriptEnding.connect(scriptEnding);
|
||||||
|
|
|
@ -73,8 +73,13 @@ file (GLOB_RECURSE QT_UI_FILES ui/*.ui)
|
||||||
# have qt5 wrap them and generate the appropriate header files
|
# have qt5 wrap them and generate the appropriate header files
|
||||||
qt5_wrap_ui(QT_UI_HEADERS "${QT_UI_FILES}")
|
qt5_wrap_ui(QT_UI_HEADERS "${QT_UI_FILES}")
|
||||||
|
|
||||||
|
# grab the resource files in resources
|
||||||
|
file (GLOB_RECURSE QT_RESOURCE_FILES resources/*.qrc)
|
||||||
|
# have qt5 wrap them and generate the appropriate source files
|
||||||
|
qt5_add_resources(QT_RESOURCES "${QT_RESOURCE_FILES}")
|
||||||
|
|
||||||
# add them to the interface source files
|
# add them to the interface source files
|
||||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${QT_UI_HEADERS}")
|
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${QT_UI_HEADERS}" "${QT_RESOURCES}")
|
||||||
|
|
||||||
set(QM ${TARGET_NAME}_en.qm)
|
set(QM ${TARGET_NAME}_en.qm)
|
||||||
set(TS ${TARGET_NAME}_en.ts)
|
set(TS ${TARGET_NAME}_en.ts)
|
||||||
|
|
|
@ -4,22 +4,22 @@
|
||||||
<context>
|
<context>
|
||||||
<name>Application</name>
|
<name>Application</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="1351"/>
|
<location filename="src/Application.cpp" line="1354"/>
|
||||||
<source>Export Voxels</source>
|
<source>Export Voxels</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="1352"/>
|
<location filename="src/Application.cpp" line="1355"/>
|
||||||
<source>Sparse Voxel Octree Files (*.svo)</source>
|
<source>Sparse Voxel Octree Files (*.svo)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="3531"/>
|
<location filename="src/Application.cpp" line="3554"/>
|
||||||
<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="3532"/>
|
<location filename="src/Application.cpp" line="3555"/>
|
||||||
<source>JavaScript Files (*.js)</source>
|
<source>JavaScript Files (*.js)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -28,19 +28,19 @@
|
||||||
<name>ChatWindow</name>
|
<name>ChatWindow</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui/chatWindow.ui" line="14"/>
|
<location filename="ui/chatWindow.ui" line="14"/>
|
||||||
<location filename="../build/interface/ui_chatWindow.h" line="113"/>
|
<location filename="../build/interface/ui_chatWindow.h" line="141"/>
|
||||||
<source>Chat</source>
|
<source>Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui/chatWindow.ui" line="41"/>
|
<location filename="ui/chatWindow.ui" line="41"/>
|
||||||
<location filename="../build/interface/ui_chatWindow.h" line="114"/>
|
<location filename="../build/interface/ui_chatWindow.h" line="142"/>
|
||||||
<source>Connecting to XMPP...</source>
|
<source>Connecting to XMPP...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui/chatWindow.ui" line="60"/>
|
<location filename="ui/chatWindow.ui" line="62"/>
|
||||||
<location filename="../build/interface/ui_chatWindow.h" line="115"/>
|
<location filename="../build/interface/ui_chatWindow.h" line="143"/>
|
||||||
<source> online now:</source>
|
<source> online now:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
14
interface/resources/images/close.svg
Normal file
14
interface/resources/images/close.svg
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<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"
|
||||||
|
viewBox="0 0 15.9 15.9" enable-background="new 0 0 15.9 15.9" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path fill="#666666" d="M15.5,13.7l-1.8,1.8c-0.2,0.2-0.6,0.4-0.9,0.4s-0.7-0.1-0.9-0.4L8,11.6L4,15.5c-0.2,0.2-0.6,0.4-0.9,0.4
|
||||||
|
s-0.7-0.1-0.9-0.4l-1.8-1.8C0.1,13.5,0,13.1,0,12.8s0.1-0.7,0.4-0.9L4.3,8L0.4,4C0.1,3.8,0,3.4,0,3.1s0.1-0.7,0.4-0.9l1.8-1.8
|
||||||
|
C2.4,0.1,2.8,0,3.1,0S3.8,0.1,4,0.4L8,4.3l3.9-3.9C12.1,0.1,12.5,0,12.8,0s0.7,0.1,0.9,0.4l1.8,1.8c0.2,0.2,0.4,0.6,0.4,0.9
|
||||||
|
S15.8,3.8,15.5,4L11.6,8l3.9,3.9c0.2,0.2,0.4,0.6,0.4,0.9S15.8,13.5,15.5,13.7z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 944 B |
5
interface/resources/resources.qrc
Normal file
5
interface/resources/resources.qrc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>images/close.svg</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
|
@ -140,9 +140,13 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
_fps(120.0f),
|
_fps(120.0f),
|
||||||
_justStarted(true),
|
_justStarted(true),
|
||||||
_voxelImporter(NULL),
|
_voxelImporter(NULL),
|
||||||
|
_importSucceded(false),
|
||||||
|
_sharedVoxelSystem(TREE_SCALE, DEFAULT_MAX_VOXELS_PER_SYSTEM, &_clipboard),
|
||||||
_wantToKillLocalVoxels(false),
|
_wantToKillLocalVoxels(false),
|
||||||
|
_viewFrustum(),
|
||||||
|
_lastQueriedViewFrustum(),
|
||||||
|
_lastQueriedTime(usecTimestampNow()),
|
||||||
_audioScope(256, 200, true),
|
_audioScope(256, 200, true),
|
||||||
_myAvatar(),
|
|
||||||
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
||||||
_mouseX(0),
|
_mouseX(0),
|
||||||
_mouseY(0),
|
_mouseY(0),
|
||||||
|
@ -1365,6 +1369,8 @@ void Application::exportVoxels(const VoxelDetail& sourceVoxel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::importVoxels() {
|
void Application::importVoxels() {
|
||||||
|
_importSucceded = false;
|
||||||
|
|
||||||
if (!_voxelImporter) {
|
if (!_voxelImporter) {
|
||||||
_voxelImporter = new VoxelImporter(_window);
|
_voxelImporter = new VoxelImporter(_window);
|
||||||
_voxelImporter->loadSettings(_settings);
|
_voxelImporter->loadSettings(_settings);
|
||||||
|
@ -1372,6 +1378,7 @@ void Application::importVoxels() {
|
||||||
|
|
||||||
if (!_voxelImporter->exec()) {
|
if (!_voxelImporter->exec()) {
|
||||||
qDebug() << "[DEBUG] Import succeeded." << endl;
|
qDebug() << "[DEBUG] Import succeeded." << endl;
|
||||||
|
_importSucceded = true;
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "[DEBUG] Import failed." << endl;
|
qDebug() << "[DEBUG] Import failed." << endl;
|
||||||
if (_sharedVoxelSystem.getTree() == _voxelImporter->getVoxelTree()) {
|
if (_sharedVoxelSystem.getTree() == _voxelImporter->getVoxelTree()) {
|
||||||
|
@ -1382,6 +1389,8 @@ void Application::importVoxels() {
|
||||||
|
|
||||||
// restore the main window's active state
|
// restore the main window's active state
|
||||||
_window->activateWindow();
|
_window->activateWindow();
|
||||||
|
|
||||||
|
emit importDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::cutVoxels(const VoxelDetail& sourceVoxel) {
|
void Application::cutVoxels(const VoxelDetail& sourceVoxel) {
|
||||||
|
@ -1473,10 +1482,9 @@ void Application::init() {
|
||||||
|
|
||||||
// Cleanup of the original shared tree
|
// Cleanup of the original shared tree
|
||||||
_sharedVoxelSystem.init();
|
_sharedVoxelSystem.init();
|
||||||
VoxelTree* tmpTree = _sharedVoxelSystem.getTree();
|
|
||||||
_sharedVoxelSystem.changeTree(&_clipboard);
|
_voxelImporter = new VoxelImporter(_window);
|
||||||
delete tmpTree;
|
|
||||||
|
|
||||||
_environment.init();
|
_environment.init();
|
||||||
|
|
||||||
_glowEffect.init();
|
_glowEffect.init();
|
||||||
|
@ -1895,8 +1903,19 @@ void Application::updateMyAvatar(float deltaTime) {
|
||||||
loadViewFrustum(_myCamera, _viewFrustum);
|
loadViewFrustum(_myCamera, _viewFrustum);
|
||||||
|
|
||||||
// Update my voxel servers with my current voxel query...
|
// Update my voxel servers with my current voxel query...
|
||||||
queryOctree(NodeType::VoxelServer, PacketTypeVoxelQuery, _voxelServerJurisdictions);
|
quint64 now = usecTimestampNow();
|
||||||
queryOctree(NodeType::ParticleServer, PacketTypeParticleQuery, _particleServerJurisdictions);
|
quint64 sinceLastQuery = now - _lastQueriedTime;
|
||||||
|
const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND;
|
||||||
|
bool queryIsDue = sinceLastQuery > TOO_LONG_SINCE_LAST_QUERY;
|
||||||
|
bool viewIsDifferentEnough = !_lastQueriedViewFrustum.isVerySimilar(_viewFrustum);
|
||||||
|
|
||||||
|
// if it's been a while since our last query or the view has significantly changed then send a query, otherwise suppress it
|
||||||
|
if (queryIsDue || viewIsDifferentEnough) {
|
||||||
|
_lastQueriedTime = now;
|
||||||
|
queryOctree(NodeType::VoxelServer, PacketTypeVoxelQuery, _voxelServerJurisdictions);
|
||||||
|
queryOctree(NodeType::ParticleServer, PacketTypeParticleQuery, _particleServerJurisdictions);
|
||||||
|
_lastQueriedViewFrustum = _viewFrustum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) {
|
void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) {
|
||||||
|
@ -2745,8 +2764,8 @@ void Application::displayStats() {
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
QString packetsString = locale.toString((int)voxelPacketsToProcess);
|
QString packetsString = locale.toString((int)voxelPacketsToProcess);
|
||||||
QString maxString = locale.toString((int)_recentMaxPackets);
|
QString maxString = locale.toString((int)_recentMaxPackets);
|
||||||
voxelStats << "Voxel Packets to Process: " << packetsString.toLocal8Bit().constData()
|
voxelStats << "Voxel Packets to Process: " << qPrintable(packetsString)
|
||||||
<< " [Recent Max: " << maxString.toLocal8Bit().constData() << "]";
|
<< " [Recent Max: " << qPrintable(maxString) << "]";
|
||||||
verticalOffset += STATS_PELS_PER_LINE;
|
verticalOffset += STATS_PELS_PER_LINE;
|
||||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||||
}
|
}
|
||||||
|
@ -2769,7 +2788,7 @@ void Application::displayStats() {
|
||||||
|
|
||||||
// Server Voxels
|
// Server Voxels
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
voxelStats << "Server voxels: " << serversTotalString.toLocal8Bit().constData();
|
voxelStats << "Server voxels: " << qPrintable(serversTotalString);
|
||||||
verticalOffset += STATS_PELS_PER_LINE;
|
verticalOffset += STATS_PELS_PER_LINE;
|
||||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||||
|
|
||||||
|
@ -2779,8 +2798,8 @@ void Application::displayStats() {
|
||||||
|
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
voxelStats <<
|
voxelStats <<
|
||||||
"Internal: " << serversInternalString.toLocal8Bit().constData() << " " <<
|
"Internal: " << qPrintable(serversInternalString) << " " <<
|
||||||
"Leaves: " << serversLeavesString.toLocal8Bit().constData() << "";
|
"Leaves: " << qPrintable(serversLeavesString) << "";
|
||||||
verticalOffset += STATS_PELS_PER_LINE;
|
verticalOffset += STATS_PELS_PER_LINE;
|
||||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||||
}
|
}
|
||||||
|
@ -2790,7 +2809,7 @@ void Application::displayStats() {
|
||||||
|
|
||||||
// Local Voxels
|
// Local Voxels
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
voxelStats << "Local voxels: " << localTotalString.toLocal8Bit().constData();
|
voxelStats << "Local voxels: " << qPrintable(localTotalString);
|
||||||
verticalOffset += STATS_PELS_PER_LINE;
|
verticalOffset += STATS_PELS_PER_LINE;
|
||||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||||
|
|
||||||
|
@ -2802,8 +2821,17 @@ void Application::displayStats() {
|
||||||
|
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
voxelStats <<
|
voxelStats <<
|
||||||
"Internal: " << localInternalString.toLocal8Bit().constData() << " " <<
|
"Internal: " << qPrintable(localInternalString) << " " <<
|
||||||
"Leaves: " << localLeavesString.toLocal8Bit().constData() << "";
|
"Leaves: " << qPrintable(localLeavesString) << "";
|
||||||
|
verticalOffset += STATS_PELS_PER_LINE;
|
||||||
|
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOD Details
|
||||||
|
if (_statsExpanded) {
|
||||||
|
voxelStats.str("");
|
||||||
|
QString displayLODDetails = Menu::getInstance()->getLODFeedbackText();
|
||||||
|
voxelStats << "LOD: You can see " << qPrintable(displayLODDetails.trimmed());
|
||||||
verticalOffset += STATS_PELS_PER_LINE;
|
verticalOffset += STATS_PELS_PER_LINE;
|
||||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,6 +156,7 @@ public:
|
||||||
VoxelTree* getVoxelTree() { return _voxels.getTree(); }
|
VoxelTree* getVoxelTree() { return _voxels.getTree(); }
|
||||||
ParticleTreeRenderer* getParticles() { return &_particles; }
|
ParticleTreeRenderer* getParticles() { return &_particles; }
|
||||||
MetavoxelSystem* getMetavoxels() { return &_metavoxels; }
|
MetavoxelSystem* getMetavoxels() { return &_metavoxels; }
|
||||||
|
bool getImportSucceded() { return _importSucceded; }
|
||||||
VoxelSystem* getSharedVoxelSystem() { return &_sharedVoxelSystem; }
|
VoxelSystem* getSharedVoxelSystem() { return &_sharedVoxelSystem; }
|
||||||
VoxelTree* getClipboard() { return &_clipboard; }
|
VoxelTree* getClipboard() { return &_clipboard; }
|
||||||
Environment* getEnvironment() { return &_environment; }
|
Environment* getEnvironment() { return &_environment; }
|
||||||
|
@ -224,6 +225,9 @@ signals:
|
||||||
/// Fired when we're rendering in-world interface elements; allows external parties to hook in.
|
/// Fired when we're rendering in-world interface elements; allows external parties to hook in.
|
||||||
void renderingInWorldInterface();
|
void renderingInWorldInterface();
|
||||||
|
|
||||||
|
/// Fired when the import window is closed
|
||||||
|
void importDone();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void domainChanged(const QString& domainHostname);
|
void domainChanged(const QString& domainHostname);
|
||||||
void updateWindowTitle();
|
void updateWindowTitle();
|
||||||
|
@ -350,13 +354,13 @@ private:
|
||||||
glm::vec3 _gravity;
|
glm::vec3 _gravity;
|
||||||
|
|
||||||
// Frame Rate Measurement
|
// Frame Rate Measurement
|
||||||
|
|
||||||
int _frameCount;
|
int _frameCount;
|
||||||
float _fps;
|
float _fps;
|
||||||
timeval _applicationStartupTime;
|
timeval _applicationStartupTime;
|
||||||
timeval _timerStart, _timerEnd;
|
timeval _timerStart, _timerEnd;
|
||||||
timeval _lastTimeUpdated;
|
timeval _lastTimeUpdated;
|
||||||
bool _justStarted;
|
bool _justStarted;
|
||||||
|
|
||||||
Stars _stars;
|
Stars _stars;
|
||||||
|
|
||||||
BuckyBalls _buckyBalls;
|
BuckyBalls _buckyBalls;
|
||||||
|
@ -364,6 +368,7 @@ private:
|
||||||
VoxelSystem _voxels;
|
VoxelSystem _voxels;
|
||||||
VoxelTree _clipboard; // if I copy/paste
|
VoxelTree _clipboard; // if I copy/paste
|
||||||
VoxelImporter* _voxelImporter;
|
VoxelImporter* _voxelImporter;
|
||||||
|
bool _importSucceded;
|
||||||
VoxelSystem _sharedVoxelSystem;
|
VoxelSystem _sharedVoxelSystem;
|
||||||
ViewFrustum _sharedVoxelSystemViewFrustum;
|
ViewFrustum _sharedVoxelSystemViewFrustum;
|
||||||
|
|
||||||
|
@ -376,6 +381,8 @@ private:
|
||||||
MetavoxelSystem _metavoxels;
|
MetavoxelSystem _metavoxels;
|
||||||
|
|
||||||
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, particles)
|
||||||
|
quint64 _lastQueriedTime;
|
||||||
|
|
||||||
Oscilloscope _audioScope;
|
Oscilloscope _audioScope;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "ClipboardScriptingInterface.h"
|
#include "ClipboardScriptingInterface.h"
|
||||||
|
|
||||||
ClipboardScriptingInterface::ClipboardScriptingInterface() {
|
ClipboardScriptingInterface::ClipboardScriptingInterface() {
|
||||||
|
connect(this, SIGNAL(readyToImport()), Application::getInstance(), SLOT(importVoxels()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClipboardScriptingInterface::cutVoxel(const VoxelDetail& sourceVoxel) {
|
void ClipboardScriptingInterface::cutVoxel(const VoxelDetail& sourceVoxel) {
|
||||||
|
@ -70,12 +71,17 @@ void ClipboardScriptingInterface::exportVoxel(float x, float y, float z, float s
|
||||||
z / (float)TREE_SCALE,
|
z / (float)TREE_SCALE,
|
||||||
s / (float)TREE_SCALE };
|
s / (float)TREE_SCALE };
|
||||||
|
|
||||||
QMetaObject::invokeMethod(Application::getInstance(), "exportVoxels",
|
Application::getInstance()->exportVoxels(sourceVoxel);
|
||||||
Q_ARG(const VoxelDetail&, sourceVoxel));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClipboardScriptingInterface::importVoxels() {
|
bool ClipboardScriptingInterface::importVoxels() {
|
||||||
QMetaObject::invokeMethod(Application::getInstance(), "importVoxels");
|
qDebug() << "[DEBUG] Importing ... ";
|
||||||
|
QEventLoop loop;
|
||||||
|
connect(Application::getInstance(), SIGNAL(importDone()), &loop, SLOT(quit()));
|
||||||
|
emit readyToImport();
|
||||||
|
loop.exec();
|
||||||
|
|
||||||
|
return Application::getInstance()->getImportSucceded();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClipboardScriptingInterface::nudgeVoxel(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec) {
|
void ClipboardScriptingInterface::nudgeVoxel(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec) {
|
||||||
|
|
|
@ -18,6 +18,9 @@ class ClipboardScriptingInterface : public QObject {
|
||||||
public:
|
public:
|
||||||
ClipboardScriptingInterface();
|
ClipboardScriptingInterface();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void readyToImport();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void cutVoxel(const VoxelDetail& sourceVoxel);
|
void cutVoxel(const VoxelDetail& sourceVoxel);
|
||||||
void cutVoxel(float x, float y, float z, float s);
|
void cutVoxel(float x, float y, float z, float s);
|
||||||
|
@ -34,7 +37,7 @@ public slots:
|
||||||
void exportVoxel(const VoxelDetail& sourceVoxel);
|
void exportVoxel(const VoxelDetail& sourceVoxel);
|
||||||
void exportVoxel(float x, float y, float z, float s);
|
void exportVoxel(float x, float y, float z, float s);
|
||||||
|
|
||||||
void importVoxels();
|
bool importVoxels();
|
||||||
|
|
||||||
void nudgeVoxel(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec);
|
void nudgeVoxel(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec);
|
||||||
void nudgeVoxel(float x, float y, float z, float s, const glm::vec3& nudgeVec);
|
void nudgeVoxel(float x, float y, float z, float s, const glm::vec3& nudgeVec);
|
||||||
|
|
|
@ -1062,15 +1062,10 @@ void Menu::showChat() {
|
||||||
if (!_chatWindow) {
|
if (!_chatWindow) {
|
||||||
_chatWindow = new ChatWindow();
|
_chatWindow = new ChatWindow();
|
||||||
QMainWindow* mainWindow = Application::getInstance()->getWindow();
|
QMainWindow* mainWindow = Application::getInstance()->getWindow();
|
||||||
|
|
||||||
// the height of the title bar is given by frameGeometry().height() - geometry().height()
|
|
||||||
// however, frameGeometry() is initialised after showing (Qt queries the OS windowing system)
|
|
||||||
// on the other hand, moving a window after showing it flickers; so just use some reasonable value
|
|
||||||
int titleBarHeight = 16;
|
|
||||||
_chatWindow->setGeometry(mainWindow->width() - _chatWindow->width(),
|
_chatWindow->setGeometry(mainWindow->width() - _chatWindow->width(),
|
||||||
mainWindow->geometry().y() + titleBarHeight,
|
mainWindow->geometry().y(),
|
||||||
_chatWindow->width(),
|
_chatWindow->width(),
|
||||||
mainWindow->height() - titleBarHeight);
|
mainWindow->height());
|
||||||
_chatWindow->show();
|
_chatWindow->show();
|
||||||
}
|
}
|
||||||
_chatWindow->raise();
|
_chatWindow->raise();
|
||||||
|
@ -1114,6 +1109,40 @@ void Menu::octreeStatsDetailsClosed() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Menu::getLODFeedbackText() {
|
||||||
|
// determine granularity feedback
|
||||||
|
int boundaryLevelAdjust = getBoundaryLevelAdjust();
|
||||||
|
QString granularityFeedback;
|
||||||
|
|
||||||
|
switch (boundaryLevelAdjust) {
|
||||||
|
case 0: {
|
||||||
|
granularityFeedback = QString("at standard granularity.");
|
||||||
|
} break;
|
||||||
|
case 1: {
|
||||||
|
granularityFeedback = QString("at half of standard granularity.");
|
||||||
|
} break;
|
||||||
|
case 2: {
|
||||||
|
granularityFeedback = QString("at a third of standard granularity.");
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
granularityFeedback = QString("at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// distance feedback
|
||||||
|
float voxelSizeScale = getVoxelSizeScale();
|
||||||
|
float relativeToDefault = voxelSizeScale / DEFAULT_OCTREE_SIZE_SCALE;
|
||||||
|
QString result;
|
||||||
|
if (relativeToDefault > 1.01) {
|
||||||
|
result = QString("%1 further %2").arg(relativeToDefault,8,'f',2).arg(granularityFeedback);
|
||||||
|
} else if (relativeToDefault > 0.99) {
|
||||||
|
result = QString("the default distance %1").arg(granularityFeedback);
|
||||||
|
} else {
|
||||||
|
result = QString("%1 of default %2").arg(relativeToDefault,8,'f',3).arg(granularityFeedback);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void Menu::autoAdjustLOD(float currentFPS) {
|
void Menu::autoAdjustLOD(float currentFPS) {
|
||||||
// NOTE: our first ~100 samples at app startup are completely all over the place, and we don't
|
// NOTE: our first ~100 samples at app startup are completely all over the place, and we don't
|
||||||
// really want to count them in our average, so we will ignore the real frame rates and stuff
|
// really want to count them in our average, so we will ignore the real frame rates and stuff
|
||||||
|
|
|
@ -85,6 +85,7 @@ public:
|
||||||
void handleViewFrustumOffsetKeyModifier(int key);
|
void handleViewFrustumOffsetKeyModifier(int key);
|
||||||
|
|
||||||
// User Tweakable LOD Items
|
// User Tweakable LOD Items
|
||||||
|
QString getLODFeedbackText();
|
||||||
void autoAdjustLOD(float currentFPS);
|
void autoAdjustLOD(float currentFPS);
|
||||||
void setVoxelSizeScale(float sizeScale);
|
void setVoxelSizeScale(float sizeScale);
|
||||||
float getVoxelSizeScale() const { return _voxelSizeScale; }
|
float getVoxelSizeScale() const { return _voxelSizeScale; }
|
||||||
|
|
|
@ -1177,8 +1177,6 @@ void VoxelSystem::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::changeTree(VoxelTree* newTree) {
|
void VoxelSystem::changeTree(VoxelTree* newTree) {
|
||||||
disconnect(_tree, 0, this, 0);
|
|
||||||
|
|
||||||
_tree = newTree;
|
_tree = newTree;
|
||||||
|
|
||||||
_tree->setDirtyBit();
|
_tree->setDirtyBit();
|
||||||
|
|
|
@ -109,9 +109,6 @@ void Avatar::simulate(float deltaTime) {
|
||||||
_shouldRenderBillboard = true;
|
_shouldRenderBillboard = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy velocity so we can use it later for acceleration
|
|
||||||
glm::vec3 oldVelocity = getVelocity();
|
|
||||||
|
|
||||||
getHand()->simulate(deltaTime, false);
|
getHand()->simulate(deltaTime, false);
|
||||||
_skeletonModel.setLODDistance(getLODDistance());
|
_skeletonModel.setLODDistance(getLODDistance());
|
||||||
|
|
||||||
|
@ -192,7 +189,7 @@ void Avatar::render(bool forShadowMap) {
|
||||||
{
|
{
|
||||||
// glow when moving in the distance
|
// glow when moving in the distance
|
||||||
|
|
||||||
const float GLOW_DISTANCE = 5.0f;
|
const float GLOW_DISTANCE = 20.0f;
|
||||||
Glower glower(_moving && lengthToTarget > GLOW_DISTANCE && !forShadowMap ? 1.0f : 0.0f);
|
Glower glower(_moving && lengthToTarget > GLOW_DISTANCE && !forShadowMap ? 1.0f : 0.0f);
|
||||||
|
|
||||||
// render body
|
// render body
|
||||||
|
|
|
@ -146,7 +146,7 @@ void SkeletonModel::applyPalmData(int jointIndex, const QVector<int>& fingerJoin
|
||||||
|
|
||||||
// rotate palm according to average finger direction
|
// rotate palm according to average finger direction
|
||||||
float directionLength = glm::length(direction);
|
float directionLength = glm::length(direction);
|
||||||
const int MIN_ROTATION_FINGERS = 3;
|
const unsigned int MIN_ROTATION_FINGERS = 3;
|
||||||
if (directionLength > EPSILON && palm.getNumFingers() >= MIN_ROTATION_FINGERS) {
|
if (directionLength > EPSILON && palm.getNumFingers() >= MIN_ROTATION_FINGERS) {
|
||||||
applyRotationDelta(jointIndex, rotationBetween(palmRotation * glm::vec3(-sign, 0.0f, 0.0f), direction), false);
|
applyRotationDelta(jointIndex, rotationBetween(palmRotation * glm::vec3(-sign, 0.0f, 0.0f), direction), false);
|
||||||
getJointRotation(jointIndex, palmRotation, true);
|
getJointRotation(jointIndex, palmRotation, true);
|
||||||
|
|
|
@ -60,7 +60,7 @@ void SixenseManager::update(float deltaTime) {
|
||||||
// Either find a palm matching the sixense controller, or make a new one
|
// Either find a palm matching the sixense controller, or make a new one
|
||||||
PalmData* palm;
|
PalmData* palm;
|
||||||
bool foundHand = false;
|
bool foundHand = false;
|
||||||
for (int j = 0; j < hand->getNumPalms(); j++) {
|
for (size_t j = 0; j < hand->getNumPalms(); j++) {
|
||||||
if (hand->getPalms()[j].getSixenseID() == data.controller_index) {
|
if (hand->getPalms()[j].getSixenseID() == data.controller_index) {
|
||||||
palm = &(hand->getPalms()[j]);
|
palm = &(hand->getPalms()[j]);
|
||||||
foundHand = true;
|
foundHand = true;
|
||||||
|
@ -128,7 +128,7 @@ void SixenseManager::update(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the controllers haven't been moved in a while, disable
|
// if the controllers haven't been moved in a while, disable
|
||||||
const int MOVEMENT_DISABLE_DURATION = 30 * 1000 * 1000;
|
const unsigned int MOVEMENT_DISABLE_DURATION = 30 * 1000 * 1000;
|
||||||
if (usecTimestampNow() - _lastMovement > MOVEMENT_DISABLE_DURATION) {
|
if (usecTimestampNow() - _lastMovement > MOVEMENT_DISABLE_DURATION) {
|
||||||
for (vector<PalmData>::iterator it = hand->getPalms().begin(); it != hand->getPalms().end(); it++) {
|
for (vector<PalmData>::iterator it = hand->getPalms().begin(); it != hand->getPalms().end(); it++) {
|
||||||
it->setActive(false);
|
it->setActive(false);
|
||||||
|
|
|
@ -66,7 +66,7 @@ template<class T> QVariant readBinaryArray(QDataStream& in) {
|
||||||
in >> compressedLength;
|
in >> compressedLength;
|
||||||
|
|
||||||
QVector<T> values;
|
QVector<T> values;
|
||||||
const int DEFLATE_ENCODING = 1;
|
const unsigned int DEFLATE_ENCODING = 1;
|
||||||
if (encoding == DEFLATE_ENCODING) {
|
if (encoding == DEFLATE_ENCODING) {
|
||||||
// preface encoded data with uncompressed length
|
// preface encoded data with uncompressed length
|
||||||
QByteArray compressed(sizeof(quint32) + compressedLength, 0);
|
QByteArray compressed(sizeof(quint32) + compressedLength, 0);
|
||||||
|
@ -163,7 +163,7 @@ FBXNode parseBinaryFBXNode(QDataStream& in) {
|
||||||
in >> nameLength;
|
in >> nameLength;
|
||||||
|
|
||||||
FBXNode node;
|
FBXNode node;
|
||||||
const int MIN_VALID_OFFSET = 40;
|
const unsigned int MIN_VALID_OFFSET = 40;
|
||||||
if (endOffset < MIN_VALID_OFFSET || nameLength == 0) {
|
if (endOffset < MIN_VALID_OFFSET || nameLength == 0) {
|
||||||
// use a null name to indicate a null node
|
// use a null name to indicate a null node
|
||||||
return node;
|
return node;
|
||||||
|
|
|
@ -328,6 +328,8 @@ bool Model::render(float alpha) {
|
||||||
|
|
||||||
glDisable(GL_COLOR_MATERIAL);
|
glDisable(GL_COLOR_MATERIAL);
|
||||||
|
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
// render opaque meshes with alpha testing
|
// render opaque meshes with alpha testing
|
||||||
|
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
|
@ -339,8 +341,6 @@ bool Model::render(float alpha) {
|
||||||
|
|
||||||
// render translucent meshes afterwards, with back face culling
|
// render translucent meshes afterwards, with back face culling
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
|
|
||||||
renderMeshes(alpha, true);
|
renderMeshes(alpha, true);
|
||||||
|
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
|
@ -28,7 +28,7 @@ const int NUM_MESSAGES_TO_TIME_STAMP = 20;
|
||||||
const QRegularExpression regexLinks("((?:(?:ftp)|(?:https?))://\\S+)");
|
const QRegularExpression regexLinks("((?:(?:ftp)|(?:https?))://\\S+)");
|
||||||
|
|
||||||
ChatWindow::ChatWindow() :
|
ChatWindow::ChatWindow() :
|
||||||
QDialog(Application::getInstance()->getGLWidget(), Qt::Tool),
|
QDialog(Application::getInstance()->getGLWidget(), Qt::CustomizeWindowHint),
|
||||||
ui(new Ui::ChatWindow),
|
ui(new Ui::ChatWindow),
|
||||||
numMessagesAfterLastTimeStamp(0)
|
numMessagesAfterLastTimeStamp(0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,10 +40,12 @@ void LocalVoxelsOverlay::update(float deltatime) {
|
||||||
_voxelSystem->init();
|
_voxelSystem->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_voxelCount != _tree->getOctreeElementsCount()) {
|
_tree->lockForRead();
|
||||||
|
if (_visible && _voxelCount != _tree->getOctreeElementsCount()) {
|
||||||
_voxelCount = _tree->getOctreeElementsCount();
|
_voxelCount = _tree->getOctreeElementsCount();
|
||||||
_voxelSystem->forceRedrawEntireTree();
|
_voxelSystem->forceRedrawEntireTree();
|
||||||
}
|
}
|
||||||
|
_tree->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalVoxelsOverlay::render() {
|
void LocalVoxelsOverlay::render() {
|
||||||
|
@ -59,8 +61,11 @@ void LocalVoxelsOverlay::render() {
|
||||||
void LocalVoxelsOverlay::setProperties(const QScriptValue &properties) {
|
void LocalVoxelsOverlay::setProperties(const QScriptValue &properties) {
|
||||||
Volume3DOverlay::setProperties(properties);
|
Volume3DOverlay::setProperties(properties);
|
||||||
|
|
||||||
|
if (properties.property("scale").isValid()) {
|
||||||
|
setSize(properties.property("scale").toVariant().toFloat());
|
||||||
|
}
|
||||||
|
|
||||||
QScriptValue treeName = properties.property("name");
|
QScriptValue treeName = properties.property("name");
|
||||||
// if "end" property was not there, check to see if they included aliases: endPoint, or p2
|
|
||||||
if (treeName.isValid()) {
|
if (treeName.isValid()) {
|
||||||
if ((_treeName = treeName.toString()) == DOMAIN_TREE_NAME) {
|
if ((_treeName = treeName.toString()) == DOMAIN_TREE_NAME) {
|
||||||
qDebug() << "addOverlay(): Can't create overlay from domain tree";
|
qDebug() << "addOverlay(): Can't create overlay from domain tree";
|
||||||
|
|
|
@ -68,7 +68,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
|
||||||
const unsigned redish = 0xfff00000;
|
const unsigned redish = 0xfff00000;
|
||||||
palette.setColor(QPalette::WindowText, QColor::fromRgb(redish));
|
palette.setColor(QPalette::WindowText, QColor::fromRgb(redish));
|
||||||
_feedback->setPalette(palette);
|
_feedback->setPalette(palette);
|
||||||
_feedback->setText(getFeedbackText());
|
_feedback->setText(Menu::getInstance()->getLODFeedbackText());
|
||||||
const int FEEDBACK_WIDTH = 350;
|
const int FEEDBACK_WIDTH = 350;
|
||||||
_feedback->setFixedWidth(FEEDBACK_WIDTH);
|
_feedback->setFixedWidth(FEEDBACK_WIDTH);
|
||||||
form->addRow("You can see... ", _feedback);
|
form->addRow("You can see... ", _feedback);
|
||||||
|
@ -81,40 +81,6 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
|
||||||
this->QDialog::setLayout(form);
|
this->QDialog::setLayout(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LodToolsDialog::getFeedbackText() {
|
|
||||||
// determine granularity feedback
|
|
||||||
int boundaryLevelAdjust = Menu::getInstance()->getBoundaryLevelAdjust();
|
|
||||||
QString granularityFeedback;
|
|
||||||
|
|
||||||
switch (boundaryLevelAdjust) {
|
|
||||||
case 0: {
|
|
||||||
granularityFeedback = QString("at standard granularity.");
|
|
||||||
} break;
|
|
||||||
case 1: {
|
|
||||||
granularityFeedback = QString("at half of standard granularity.");
|
|
||||||
} break;
|
|
||||||
case 2: {
|
|
||||||
granularityFeedback = QString("at a third of standard granularity.");
|
|
||||||
} break;
|
|
||||||
default: {
|
|
||||||
granularityFeedback = QString("at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1);
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// distance feedback
|
|
||||||
float voxelSizeScale = Menu::getInstance()->getVoxelSizeScale();
|
|
||||||
float relativeToDefault = voxelSizeScale / DEFAULT_OCTREE_SIZE_SCALE;
|
|
||||||
QString result;
|
|
||||||
if (relativeToDefault > 1.01) {
|
|
||||||
result = QString("%1 further %2").arg(relativeToDefault,8,'f',2).arg(granularityFeedback);
|
|
||||||
} else if (relativeToDefault > 0.99) {
|
|
||||||
result = QString("the default distance %1").arg(granularityFeedback);
|
|
||||||
} else {
|
|
||||||
result = QString("%1 of default %2").arg(relativeToDefault,8,'f',3).arg(granularityFeedback);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LodToolsDialog::~LodToolsDialog() {
|
LodToolsDialog::~LodToolsDialog() {
|
||||||
delete _feedback;
|
delete _feedback;
|
||||||
delete _lodSize;
|
delete _lodSize;
|
||||||
|
@ -124,19 +90,19 @@ LodToolsDialog::~LodToolsDialog() {
|
||||||
void LodToolsDialog::reloadSliders() {
|
void LodToolsDialog::reloadSliders() {
|
||||||
_lodSize->setValue(Menu::getInstance()->getVoxelSizeScale() / TREE_SCALE);
|
_lodSize->setValue(Menu::getInstance()->getVoxelSizeScale() / TREE_SCALE);
|
||||||
_boundaryLevelAdjust->setValue(Menu::getInstance()->getBoundaryLevelAdjust());
|
_boundaryLevelAdjust->setValue(Menu::getInstance()->getBoundaryLevelAdjust());
|
||||||
_feedback->setText(getFeedbackText());
|
_feedback->setText(Menu::getInstance()->getLODFeedbackText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LodToolsDialog::sizeScaleValueChanged(int value) {
|
void LodToolsDialog::sizeScaleValueChanged(int value) {
|
||||||
float realValue = value * TREE_SCALE;
|
float realValue = value * TREE_SCALE;
|
||||||
Menu::getInstance()->setVoxelSizeScale(realValue);
|
Menu::getInstance()->setVoxelSizeScale(realValue);
|
||||||
|
|
||||||
_feedback->setText(getFeedbackText());
|
_feedback->setText(Menu::getInstance()->getLODFeedbackText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LodToolsDialog::boundaryLevelValueChanged(int value) {
|
void LodToolsDialog::boundaryLevelValueChanged(int value) {
|
||||||
Menu::getInstance()->setBoundaryLevelAdjust(value);
|
Menu::getInstance()->setBoundaryLevelAdjust(value);
|
||||||
_feedback->setText(getFeedbackText());
|
_feedback->setText(Menu::getInstance()->getLODFeedbackText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LodToolsDialog::resetClicked(bool checked) {
|
void LodToolsDialog::resetClicked(bool checked) {
|
||||||
|
|
|
@ -36,8 +36,6 @@ protected:
|
||||||
void closeEvent(QCloseEvent*);
|
void closeEvent(QCloseEvent*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString getFeedbackText();
|
|
||||||
|
|
||||||
QSlider* _lodSize;
|
QSlider* _lodSize;
|
||||||
QSlider* _boundaryLevelAdjust;
|
QSlider* _boundaryLevelAdjust;
|
||||||
QLabel* _feedback;
|
QLabel* _feedback;
|
||||||
|
|
|
@ -387,7 +387,7 @@ void BoxSetTool::render() {
|
||||||
|
|
||||||
glm::quat rotation = _editor->getGridRotation();
|
glm::quat rotation = _editor->getGridRotation();
|
||||||
glm::vec3 axis = glm::axis(rotation);
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
|
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||||
|
|
||||||
glm::quat inverseRotation = glm::inverse(rotation);
|
glm::quat inverseRotation = glm::inverse(rotation);
|
||||||
glm::vec3 rayOrigin = inverseRotation * Application::getInstance()->getMouseRayOrigin();
|
glm::vec3 rayOrigin = inverseRotation * Application::getInstance()->getMouseRayOrigin();
|
||||||
|
|
|
@ -157,9 +157,9 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) {
|
||||||
|
|
||||||
statsValue.str("");
|
statsValue.str("");
|
||||||
statsValue <<
|
statsValue <<
|
||||||
"Total: " << localTotalString.toLocal8Bit().constData() << " / " <<
|
"Total: " << qPrintable(localTotalString) << " / " <<
|
||||||
"Internal: " << localInternalString.toLocal8Bit().constData() << " / " <<
|
"Internal: " << qPrintable(localInternalString) << " / " <<
|
||||||
"Leaves: " << localLeavesString.toLocal8Bit().constData() << "";
|
"Leaves: " << qPrintable(localLeavesString) << "";
|
||||||
label->setText(statsValue.str().c_str());
|
label->setText(statsValue.str().c_str());
|
||||||
|
|
||||||
// iterate all the current voxel stats, and list their sending modes, total their voxels, etc...
|
// iterate all the current voxel stats, and list their sending modes, total their voxels, etc...
|
||||||
|
@ -212,9 +212,9 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) {
|
||||||
label = _labels[_serverVoxels];
|
label = _labels[_serverVoxels];
|
||||||
statsValue.str("");
|
statsValue.str("");
|
||||||
statsValue <<
|
statsValue <<
|
||||||
"Total: " << serversTotalString.toLocal8Bit().constData() << " / " <<
|
"Total: " << qPrintable(serversTotalString) << " / " <<
|
||||||
"Internal: " << serversInternalString.toLocal8Bit().constData() << " / " <<
|
"Internal: " << qPrintable(serversInternalString) << " / " <<
|
||||||
"Leaves: " << serversLeavesString.toLocal8Bit().constData() << "";
|
"Leaves: " << qPrintable(serversLeavesString) << "";
|
||||||
label->setText(statsValue.str().c_str());
|
label->setText(statsValue.str().c_str());
|
||||||
|
|
||||||
showAllOctreeServers();
|
showAllOctreeServers();
|
||||||
|
@ -290,7 +290,7 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
|
||||||
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||||
serverBounds.scale(TREE_SCALE);
|
serverBounds.scale(TREE_SCALE);
|
||||||
serverDetails << " jurisdiction: "
|
serverDetails << " jurisdiction: "
|
||||||
<< rootCodeHex.toLocal8Bit().constData()
|
<< qPrintable(rootCodeHex)
|
||||||
<< " ["
|
<< " ["
|
||||||
<< rootDetails.x << ", "
|
<< rootDetails.x << ", "
|
||||||
<< rootDetails.y << ", "
|
<< rootDetails.y << ", "
|
||||||
|
@ -315,13 +315,25 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
|
||||||
const unsigned long USECS_PER_MSEC = 1000;
|
const unsigned long USECS_PER_MSEC = 1000;
|
||||||
float lastFullEncode = stats.getLastFullTotalEncodeTime() / USECS_PER_MSEC;
|
float lastFullEncode = stats.getLastFullTotalEncodeTime() / USECS_PER_MSEC;
|
||||||
float lastFullSend = stats.getLastFullElapsedTime() / USECS_PER_MSEC;
|
float lastFullSend = stats.getLastFullElapsedTime() / USECS_PER_MSEC;
|
||||||
|
float lastFullSendInSeconds = stats.getLastFullElapsedTime() / USECS_PER_SECOND;
|
||||||
|
float lastFullPackets = stats.getLastFullTotalPackets();
|
||||||
|
float lastFullPPS = lastFullPackets;
|
||||||
|
if (lastFullSendInSeconds > 0) {
|
||||||
|
lastFullPPS = lastFullPackets / lastFullSendInSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
QString lastFullEncodeString = locale.toString(lastFullEncode);
|
QString lastFullEncodeString = locale.toString(lastFullEncode);
|
||||||
QString lastFullSendString = locale.toString(lastFullSend);
|
QString lastFullSendString = locale.toString(lastFullSend);
|
||||||
|
QString lastFullPacketsString = locale.toString(lastFullPackets);
|
||||||
|
QString lastFullBytesString = locale.toString((uint)stats.getLastFullTotalBytes());
|
||||||
|
QString lastFullPPSString = locale.toString(lastFullPPS);
|
||||||
|
|
||||||
extraDetails << "<br/>" << "Last Full Scene... " <<
|
extraDetails << "<br/>" << "Last Full Scene... " <<
|
||||||
"Encode Time: " << lastFullEncodeString.toLocal8Bit().constData() << " ms " <<
|
"Encode: " << qPrintable(lastFullEncodeString) << " ms " <<
|
||||||
"Send Time: " << lastFullSendString.toLocal8Bit().constData() << " ms ";
|
"Send: " << qPrintable(lastFullSendString) << " ms " <<
|
||||||
|
"Packets: " << qPrintable(lastFullPacketsString) << " " <<
|
||||||
|
"Bytes: " << qPrintable(lastFullBytesString) << " " <<
|
||||||
|
"Rate: " << qPrintable(lastFullPPSString) << " PPS";
|
||||||
|
|
||||||
for (int i = 0; i < OctreeSceneStats::ITEM_COUNT; i++) {
|
for (int i = 0; i < OctreeSceneStats::ITEM_COUNT; i++) {
|
||||||
OctreeSceneStats::Item item = (OctreeSceneStats::Item)(i);
|
OctreeSceneStats::Item item = (OctreeSceneStats::Item)(i);
|
||||||
|
@ -334,42 +346,51 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
|
||||||
QString internalString = locale.toString((uint)stats.getTotalInternal());
|
QString internalString = locale.toString((uint)stats.getTotalInternal());
|
||||||
QString leavesString = locale.toString((uint)stats.getTotalLeaves());
|
QString leavesString = locale.toString((uint)stats.getTotalLeaves());
|
||||||
|
|
||||||
serverDetails << "<br/>" << "Node UUID: " <<
|
serverDetails << "<br/>" << "Node UUID: " << qPrintable(nodeUUID.toString()) << " ";
|
||||||
nodeUUID.toString().toLocal8Bit().constData() << " ";
|
|
||||||
|
|
||||||
serverDetails << "<br/>" << "Voxels: " <<
|
serverDetails << "<br/>" << "Voxels: " <<
|
||||||
totalString.toLocal8Bit().constData() << " total " <<
|
qPrintable(totalString) << " total " <<
|
||||||
internalString.toLocal8Bit().constData() << " internal " <<
|
qPrintable(internalString) << " internal " <<
|
||||||
leavesString.toLocal8Bit().constData() << " leaves ";
|
qPrintable(leavesString) << " leaves ";
|
||||||
|
|
||||||
QString incomingPacketsString = locale.toString((uint)stats.getIncomingPackets());
|
QString incomingPacketsString = locale.toString((uint)stats.getIncomingPackets());
|
||||||
QString incomingBytesString = locale.toString((uint)stats.getIncomingBytes());
|
QString incomingBytesString = locale.toString((uint)stats.getIncomingBytes());
|
||||||
QString incomingWastedBytesString = locale.toString((uint)stats.getIncomingWastedBytes());
|
QString incomingWastedBytesString = locale.toString((uint)stats.getIncomingWastedBytes());
|
||||||
QString incomingOutOfOrderString = locale.toString((uint)stats.getIncomingOutOfOrder());
|
QString incomingOutOfOrderString = locale.toString((uint)stats.getIncomingOutOfOrder());
|
||||||
|
QString incomingLateString = locale.toString((uint)stats.getIncomingLate());
|
||||||
|
QString incomingReallyLateString = locale.toString((uint)stats.getIncomingReallyLate());
|
||||||
|
QString incomingEarlyString = locale.toString((uint)stats.getIncomingEarly());
|
||||||
QString incomingLikelyLostString = locale.toString((uint)stats.getIncomingLikelyLost());
|
QString incomingLikelyLostString = locale.toString((uint)stats.getIncomingLikelyLost());
|
||||||
|
QString incomingRecovered = locale.toString((uint)stats.getIncomingRecovered());
|
||||||
|
QString incomingDuplicateString = locale.toString((uint)stats.getIncomingPossibleDuplicate());
|
||||||
|
|
||||||
int clockSkewInMS = node->getClockSkewUsec() / (int)USECS_PER_MSEC;
|
int clockSkewInMS = node->getClockSkewUsec() / (int)USECS_PER_MSEC;
|
||||||
QString incomingFlightTimeString = locale.toString((int)stats.getIncomingFlightTimeAverage());
|
QString incomingFlightTimeString = locale.toString((int)stats.getIncomingFlightTimeAverage());
|
||||||
QString incomingPingTimeString = locale.toString(node->getPingMs());
|
QString incomingPingTimeString = locale.toString(node->getPingMs());
|
||||||
QString incomingClockSkewString = locale.toString(clockSkewInMS);
|
QString incomingClockSkewString = locale.toString(clockSkewInMS);
|
||||||
|
|
||||||
serverDetails << "<br/>" << "Incoming Packets: " <<
|
serverDetails << "<br/>" << "Incoming Packets: " << qPrintable(incomingPacketsString) <<
|
||||||
incomingPacketsString.toLocal8Bit().constData() <<
|
"/ Lost: " << qPrintable(incomingLikelyLostString) <<
|
||||||
" Out of Order: " << incomingOutOfOrderString.toLocal8Bit().constData() <<
|
"/ Recovered: " << qPrintable(incomingRecovered);
|
||||||
" Likely Lost: " << incomingLikelyLostString.toLocal8Bit().constData();
|
|
||||||
|
serverDetails << "<br/>" << " Out of Order: " << qPrintable(incomingOutOfOrderString) <<
|
||||||
|
"/ Early: " << qPrintable(incomingEarlyString) <<
|
||||||
|
"/ Late: " << qPrintable(incomingLateString) <<
|
||||||
|
"/ Really Late: " << qPrintable(incomingReallyLateString) <<
|
||||||
|
"/ Duplicate: " << qPrintable(incomingDuplicateString);
|
||||||
|
|
||||||
serverDetails << "<br/>" <<
|
serverDetails << "<br/>" <<
|
||||||
" Average Flight Time: " << incomingFlightTimeString.toLocal8Bit().constData() << " msecs";
|
" Average Flight Time: " << qPrintable(incomingFlightTimeString) << " msecs";
|
||||||
|
|
||||||
serverDetails << "<br/>" <<
|
serverDetails << "<br/>" <<
|
||||||
" Average Ping Time: " << incomingPingTimeString.toLocal8Bit().constData() << " msecs";
|
" Average Ping Time: " << qPrintable(incomingPingTimeString) << " msecs";
|
||||||
|
|
||||||
serverDetails << "<br/>" <<
|
serverDetails << "<br/>" <<
|
||||||
" Average Clock Skew: " << incomingClockSkewString.toLocal8Bit().constData() << " msecs";
|
" Average Clock Skew: " << qPrintable(incomingClockSkewString) << " msecs";
|
||||||
|
|
||||||
serverDetails << "<br/>" << "Incoming" <<
|
serverDetails << "<br/>" << "Incoming" <<
|
||||||
" Bytes: " << incomingBytesString.toLocal8Bit().constData() <<
|
" Bytes: " << qPrintable(incomingBytesString) <<
|
||||||
" Wasted Bytes: " << incomingWastedBytesString.toLocal8Bit().constData();
|
" Wasted Bytes: " << qPrintable(incomingWastedBytesString);
|
||||||
|
|
||||||
serverDetails << extraDetails.str();
|
serverDetails << extraDetails.str();
|
||||||
if (_extraServerDetails[serverCount-1] == MORE) {
|
if (_extraServerDetails[serverCount-1] == MORE) {
|
||||||
|
|
|
@ -46,20 +46,53 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="numOnlineLabel">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<property name="sizePolicy">
|
<item>
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
<widget class="QLabel" name="numOnlineLabel">
|
||||||
<horstretch>0</horstretch>
|
<property name="sizePolicy">
|
||||||
<verstretch>0</verstretch>
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
</sizepolicy>
|
<horstretch>0</horstretch>
|
||||||
</property>
|
<verstretch>0</verstretch>
|
||||||
<property name="styleSheet">
|
</sizepolicy>
|
||||||
<string notr="true">font-weight: bold; color: palette(shadow); margin-bottom: 4px;</string>
|
</property>
|
||||||
</property>
|
<property name="styleSheet">
|
||||||
<property name="text">
|
<string notr="true">font-weight: bold; color: palette(shadow); margin-bottom: 4px;</string>
|
||||||
<string> online now:</string>
|
</property>
|
||||||
</property>
|
<property name="text">
|
||||||
</widget>
|
<string> online now:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="closeButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16</width>
|
||||||
|
<height>16</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::NoFocus</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../resources/resources.qrc">
|
||||||
|
<normaloff>:/images/close.svg</normaloff>:/images/close.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="usersWidget" native="true"/>
|
<widget class="QWidget" name="usersWidget" native="true"/>
|
||||||
|
@ -81,7 +114,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>358</width>
|
<width>358</width>
|
||||||
<height>448</height>
|
<height>452</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
|
@ -122,7 +155,10 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">font-family: Helvetica, Arial, sans-serif;</string>
|
<string notr="true">border-color: palette(dark); border-style: solid; border-left-width: 1px; border-right-width: 1px; border-bottom-width: 1px;</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="horizontalScrollBarPolicy">
|
<property name="horizontalScrollBarPolicy">
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
@ -130,6 +166,9 @@
|
||||||
<property name="sizeAdjustPolicy">
|
<property name="sizeAdjustPolicy">
|
||||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="tabChangesFocus">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -138,6 +177,25 @@
|
||||||
<tabstop>messagePlainTextEdit</tabstop>
|
<tabstop>messagePlainTextEdit</tabstop>
|
||||||
<tabstop>messagesScrollArea</tabstop>
|
<tabstop>messagesScrollArea</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources>
|
||||||
<connections/>
|
<include location="../resources/resources.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>closeButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>ChatWindow</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>342</x>
|
||||||
|
<y>42</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>550</x>
|
||||||
|
<y>42</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -155,27 +155,27 @@ Attribute::Attribute(const QString& name) :
|
||||||
Attribute::~Attribute() {
|
Attribute::~Attribute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::read(MetavoxelData& data, MetavoxelStreamState& state) {
|
void Attribute::readMetavoxelRoot(MetavoxelData& data, MetavoxelStreamState& state) {
|
||||||
data.createRoot(state.attribute)->read(state);
|
data.createRoot(state.attribute)->read(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::write(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
void Attribute::writeMetavoxelRoot(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
||||||
root.write(state);
|
root.write(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::readDelta(MetavoxelData& data, const MetavoxelNode& reference, MetavoxelStreamState& state) {
|
void Attribute::readMetavoxelDelta(MetavoxelData& data, const MetavoxelNode& reference, MetavoxelStreamState& state) {
|
||||||
data.createRoot(state.attribute)->readDelta(reference, state);
|
data.createRoot(state.attribute)->readDelta(reference, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::writeDelta(const MetavoxelNode& root, const MetavoxelNode& reference, MetavoxelStreamState& state) {
|
void Attribute::writeMetavoxelDelta(const MetavoxelNode& root, const MetavoxelNode& reference, MetavoxelStreamState& state) {
|
||||||
root.writeDelta(reference, state);
|
root.writeDelta(reference, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::readSubdivision(MetavoxelData& data, MetavoxelStreamState& state) {
|
void Attribute::readMetavoxelSubdivision(MetavoxelData& data, MetavoxelStreamState& state) {
|
||||||
data.getRoot(state.attribute)->readSubdivision(state);
|
data.getRoot(state.attribute)->readSubdivision(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::writeSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
void Attribute::writeMetavoxelSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
||||||
root.writeSubdivision(state);
|
root.writeSubdivision(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ SpannerSetAttribute::SpannerSetAttribute(const QString& name, const QMetaObject*
|
||||||
SharedObjectSetAttribute(name, metaObject) {
|
SharedObjectSetAttribute(name, metaObject) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpannerSetAttribute::read(MetavoxelData& data, MetavoxelStreamState& state) {
|
void SpannerSetAttribute::readMetavoxelRoot(MetavoxelData& data, MetavoxelStreamState& state) {
|
||||||
forever {
|
forever {
|
||||||
SharedObjectPointer object;
|
SharedObjectPointer object;
|
||||||
state.stream >> object;
|
state.stream >> object;
|
||||||
|
@ -338,13 +338,14 @@ void SpannerSetAttribute::read(MetavoxelData& data, MetavoxelStreamState& state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpannerSetAttribute::write(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
void SpannerSetAttribute::writeMetavoxelRoot(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
||||||
Spanner::incrementVisit();
|
Spanner::incrementVisit();
|
||||||
root.writeSpanners(state);
|
root.writeSpanners(state);
|
||||||
state.stream << SharedObjectPointer();
|
state.stream << SharedObjectPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpannerSetAttribute::readDelta(MetavoxelData& data, const MetavoxelNode& reference, MetavoxelStreamState& state) {
|
void SpannerSetAttribute::readMetavoxelDelta(MetavoxelData& data,
|
||||||
|
const MetavoxelNode& reference, MetavoxelStreamState& state) {
|
||||||
forever {
|
forever {
|
||||||
SharedObjectPointer object;
|
SharedObjectPointer object;
|
||||||
state.stream >> object;
|
state.stream >> object;
|
||||||
|
@ -355,13 +356,14 @@ void SpannerSetAttribute::readDelta(MetavoxelData& data, const MetavoxelNode& re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpannerSetAttribute::writeDelta(const MetavoxelNode& root, const MetavoxelNode& reference, MetavoxelStreamState& state) {
|
void SpannerSetAttribute::writeMetavoxelDelta(const MetavoxelNode& root,
|
||||||
|
const MetavoxelNode& reference, MetavoxelStreamState& state) {
|
||||||
Spanner::incrementVisit();
|
Spanner::incrementVisit();
|
||||||
root.writeSpannerDelta(reference, state);
|
root.writeSpannerDelta(reference, state);
|
||||||
state.stream << SharedObjectPointer();
|
state.stream << SharedObjectPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpannerSetAttribute::readSubdivision(MetavoxelData& data, MetavoxelStreamState& state) {
|
void SpannerSetAttribute::readMetavoxelSubdivision(MetavoxelData& data, MetavoxelStreamState& state) {
|
||||||
forever {
|
forever {
|
||||||
SharedObjectPointer object;
|
SharedObjectPointer object;
|
||||||
state.stream >> object;
|
state.stream >> object;
|
||||||
|
@ -372,7 +374,7 @@ void SpannerSetAttribute::readSubdivision(MetavoxelData& data, MetavoxelStreamSt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpannerSetAttribute::writeSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
void SpannerSetAttribute::writeMetavoxelSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
||||||
Spanner::incrementVisit();
|
Spanner::incrementVisit();
|
||||||
root.writeSpannerSubdivision(state);
|
root.writeSpannerSubdivision(state);
|
||||||
state.stream << SharedObjectPointer();
|
state.stream << SharedObjectPointer();
|
||||||
|
|
|
@ -177,14 +177,14 @@ public:
|
||||||
virtual void readDelta(Bitstream& in, void*& value, void* reference, bool isLeaf) const { read(in, value, isLeaf); }
|
virtual void readDelta(Bitstream& in, void*& value, void* reference, bool isLeaf) const { read(in, value, isLeaf); }
|
||||||
virtual void writeDelta(Bitstream& out, void* value, void* reference, bool isLeaf) const { write(out, value, isLeaf); }
|
virtual void writeDelta(Bitstream& out, void* value, void* reference, bool isLeaf) const { write(out, value, isLeaf); }
|
||||||
|
|
||||||
virtual void read(MetavoxelData& data, MetavoxelStreamState& state);
|
virtual void readMetavoxelRoot(MetavoxelData& data, MetavoxelStreamState& state);
|
||||||
virtual void write(const MetavoxelNode& root, MetavoxelStreamState& state);
|
virtual void writeMetavoxelRoot(const MetavoxelNode& root, MetavoxelStreamState& state);
|
||||||
|
|
||||||
virtual void readDelta(MetavoxelData& data, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
virtual void readMetavoxelDelta(MetavoxelData& data, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
||||||
virtual void writeDelta(const MetavoxelNode& root, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
virtual void writeMetavoxelDelta(const MetavoxelNode& root, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
||||||
|
|
||||||
virtual void readSubdivision(MetavoxelData& data, MetavoxelStreamState& state);
|
virtual void readMetavoxelSubdivision(MetavoxelData& data, MetavoxelStreamState& state);
|
||||||
virtual void writeSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state);
|
virtual void writeMetavoxelSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state);
|
||||||
|
|
||||||
virtual bool equal(void* first, void* second) const = 0;
|
virtual bool equal(void* first, void* second) const = 0;
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ template<class T, int bits> inline bool SimpleInlineAttribute<T, bits>::merge(vo
|
||||||
/// Provides appropriate averaging for RGBA values.
|
/// Provides appropriate averaging for RGBA values.
|
||||||
class QRgbAttribute : public InlineAttribute<QRgb> {
|
class QRgbAttribute : public InlineAttribute<QRgb> {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(int defaultValue MEMBER _defaultValue)
|
Q_PROPERTY(uint defaultValue MEMBER _defaultValue)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -355,14 +355,14 @@ public:
|
||||||
Q_INVOKABLE SpannerSetAttribute(const QString& name = QString(),
|
Q_INVOKABLE SpannerSetAttribute(const QString& name = QString(),
|
||||||
const QMetaObject* metaObject = &SharedObject::staticMetaObject);
|
const QMetaObject* metaObject = &SharedObject::staticMetaObject);
|
||||||
|
|
||||||
virtual void read(MetavoxelData& data, MetavoxelStreamState& state);
|
virtual void readMetavoxelRoot(MetavoxelData& data, MetavoxelStreamState& state);
|
||||||
virtual void write(const MetavoxelNode& root, MetavoxelStreamState& state);
|
virtual void writeMetavoxelRoot(const MetavoxelNode& root, MetavoxelStreamState& state);
|
||||||
|
|
||||||
virtual void readDelta(MetavoxelData& data, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
virtual void readMetavoxelDelta(MetavoxelData& data, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
||||||
virtual void writeDelta(const MetavoxelNode& root, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
virtual void writeMetavoxelDelta(const MetavoxelNode& root, const MetavoxelNode& reference, MetavoxelStreamState& state);
|
||||||
|
|
||||||
virtual void readSubdivision(MetavoxelData& data, MetavoxelStreamState& state);
|
virtual void readMetavoxelSubdivision(MetavoxelData& data, MetavoxelStreamState& state);
|
||||||
virtual void writeSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state);
|
virtual void writeMetavoxelSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__interface__AttributeRegistry__) */
|
#endif /* defined(__interface__AttributeRegistry__) */
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
REGISTER_SIMPLE_TYPE_STREAMER(bool)
|
REGISTER_SIMPLE_TYPE_STREAMER(bool)
|
||||||
REGISTER_SIMPLE_TYPE_STREAMER(int)
|
REGISTER_SIMPLE_TYPE_STREAMER(int)
|
||||||
|
REGISTER_SIMPLE_TYPE_STREAMER(uint)
|
||||||
REGISTER_SIMPLE_TYPE_STREAMER(float)
|
REGISTER_SIMPLE_TYPE_STREAMER(float)
|
||||||
REGISTER_SIMPLE_TYPE_STREAMER(QByteArray)
|
REGISTER_SIMPLE_TYPE_STREAMER(QByteArray)
|
||||||
REGISTER_SIMPLE_TYPE_STREAMER(QColor)
|
REGISTER_SIMPLE_TYPE_STREAMER(QColor)
|
||||||
|
@ -238,6 +239,17 @@ Bitstream& Bitstream::operator>>(int& value) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bitstream& Bitstream::operator<<(uint value) {
|
||||||
|
return write(&value, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitstream& Bitstream::operator>>(uint& value) {
|
||||||
|
quint32 sizedValue;
|
||||||
|
read(&sizedValue, 32);
|
||||||
|
value = sizedValue;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
Bitstream& Bitstream::operator<<(float value) {
|
Bitstream& Bitstream::operator<<(float value) {
|
||||||
return write(&value, 32);
|
return write(&value, 32);
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,6 +254,9 @@ public:
|
||||||
Bitstream& operator<<(int value);
|
Bitstream& operator<<(int value);
|
||||||
Bitstream& operator>>(int& value);
|
Bitstream& operator>>(int& value);
|
||||||
|
|
||||||
|
Bitstream& operator<<(uint value);
|
||||||
|
Bitstream& operator>>(uint& value);
|
||||||
|
|
||||||
Bitstream& operator<<(float value);
|
Bitstream& operator<<(float value);
|
||||||
Bitstream& operator>>(float& value);
|
Bitstream& operator>>(float& value);
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ public:
|
||||||
Spanner* getSpanner() const { return _spanner; }
|
Spanner* getSpanner() const { return _spanner; }
|
||||||
float getDistance() const { return _distance; }
|
float getDistance() const { return _distance; }
|
||||||
|
|
||||||
virtual bool visit(Spanner* spanner, float distance);
|
virtual bool visitSpanner(Spanner* spanner, float distance);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ FirstRaySpannerIntersectionVisitor::FirstRaySpannerIntersectionVisitor(
|
||||||
_spanner(NULL) {
|
_spanner(NULL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FirstRaySpannerIntersectionVisitor::visit(Spanner* spanner, float distance) {
|
bool FirstRaySpannerIntersectionVisitor::visitSpanner(Spanner* spanner, float distance) {
|
||||||
_spanner = spanner;
|
_spanner = spanner;
|
||||||
_distance = distance;
|
_distance = distance;
|
||||||
return false;
|
return false;
|
||||||
|
@ -312,7 +312,7 @@ void MetavoxelData::read(Bitstream& in, const MetavoxelLOD& lod) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
MetavoxelStreamState state = { getMinimum(), _size, attribute, in, lod, lod };
|
MetavoxelStreamState state = { getMinimum(), _size, attribute, in, lod, lod };
|
||||||
attribute->read(*this, state);
|
attribute->readMetavoxelRoot(*this, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ void MetavoxelData::write(Bitstream& out, const MetavoxelLOD& lod) const {
|
||||||
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) {
|
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) {
|
||||||
out << it.key();
|
out << it.key();
|
||||||
MetavoxelStreamState state = { getMinimum(), _size, it.key(), out, lod, lod };
|
MetavoxelStreamState state = { getMinimum(), _size, it.key(), out, lod, lod };
|
||||||
it.key()->write(*it.value(), state);
|
it.key()->writeMetavoxelRoot(*it.value(), state);
|
||||||
}
|
}
|
||||||
out << AttributePointer();
|
out << AttributePointer();
|
||||||
}
|
}
|
||||||
|
@ -360,13 +360,13 @@ void MetavoxelData::readDelta(const MetavoxelData& reference, const MetavoxelLOD
|
||||||
in >> changed;
|
in >> changed;
|
||||||
if (changed) {
|
if (changed) {
|
||||||
oldRoot->incrementReferenceCount();
|
oldRoot->incrementReferenceCount();
|
||||||
attribute->readDelta(*this, *oldRoot, state);
|
attribute->readMetavoxelDelta(*this, *oldRoot, state);
|
||||||
oldRoot->decrementReferenceCount(attribute);
|
oldRoot->decrementReferenceCount(attribute);
|
||||||
} else {
|
} else {
|
||||||
attribute->readSubdivision(*this, state);
|
attribute->readMetavoxelSubdivision(*this, state);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
attribute->read(*this, state);
|
attribute->readMetavoxelRoot(*this, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,13 +415,13 @@ void MetavoxelData::writeDelta(const MetavoxelData& reference, const MetavoxelLO
|
||||||
if (referenceRoot) {
|
if (referenceRoot) {
|
||||||
if (it.value() == referenceRoot) {
|
if (it.value() == referenceRoot) {
|
||||||
out << false;
|
out << false;
|
||||||
it.key()->writeSubdivision(*it.value(), state);
|
it.key()->writeMetavoxelSubdivision(*it.value(), state);
|
||||||
} else {
|
} else {
|
||||||
out << true;
|
out << true;
|
||||||
it.key()->writeDelta(*it.value(), *referenceRoot, state);
|
it.key()->writeMetavoxelDelta(*it.value(), *referenceRoot, state);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
it.key()->write(*it.value(), state);
|
it.key()->writeMetavoxelRoot(*it.value(), state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -938,7 +938,7 @@ int RaySpannerIntersectionVisitor::visit(MetavoxelInfo& info, float distance) {
|
||||||
}
|
}
|
||||||
qStableSort(spannerDistances);
|
qStableSort(spannerDistances);
|
||||||
foreach (const SpannerDistance& spannerDistance, spannerDistances) {
|
foreach (const SpannerDistance& spannerDistance, spannerDistances) {
|
||||||
if (!visit(spannerDistance.spanner, spannerDistance.distance)) {
|
if (!visitSpanner(spannerDistance.spanner, spannerDistance.distance)) {
|
||||||
return SHORT_CIRCUIT;
|
return SHORT_CIRCUIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,7 +302,7 @@ public:
|
||||||
|
|
||||||
/// Visits a spanner that the ray intersects.
|
/// Visits a spanner that the ray intersects.
|
||||||
/// \return true to continue, false to short-circuit the tour
|
/// \return true to continue, false to short-circuit the tour
|
||||||
virtual bool visit(Spanner* spanner, float distance) = 0;
|
virtual bool visitSpanner(Spanner* spanner, float distance) = 0;
|
||||||
|
|
||||||
virtual void prepare();
|
virtual void prepare();
|
||||||
virtual int visit(MetavoxelInfo& info, float distance);
|
virtual int visit(MetavoxelInfo& info, float distance);
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <fstream> // to load voxels from file
|
#include <fstream> // to load voxels from file
|
||||||
|
|
||||||
#include <glm/gtc/noise.hpp>
|
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include "CoverageMap.h"
|
#include "CoverageMap.h"
|
||||||
|
|
|
@ -18,20 +18,32 @@
|
||||||
#include "OctreeSceneStats.h"
|
#include "OctreeSceneStats.h"
|
||||||
|
|
||||||
|
|
||||||
|
const uint16_t MAX_MISSING_SEQUENCE = 100; /// how many items in our _missingSequenceNumbers before we start to prune them
|
||||||
|
const uint16_t MAX_MISSING_SEQUENCE_OLD_AGE = 1000; /// age we allow items in _missingSequenceNumbers to be before pruning
|
||||||
|
|
||||||
|
|
||||||
const int samples = 100;
|
const int samples = 100;
|
||||||
OctreeSceneStats::OctreeSceneStats() :
|
OctreeSceneStats::OctreeSceneStats() :
|
||||||
_isReadyToSend(false),
|
_isReadyToSend(false),
|
||||||
_isStarted(false),
|
_isStarted(false),
|
||||||
_lastFullElapsed(0),
|
_lastFullElapsed(0),
|
||||||
|
_lastFullTotalEncodeTime(0),
|
||||||
|
_lastFullTotalPackets(0),
|
||||||
|
_lastFullTotalBytes(0),
|
||||||
|
|
||||||
_elapsedAverage(samples),
|
_elapsedAverage(samples),
|
||||||
_bitsPerOctreeAverage(samples),
|
_bitsPerOctreeAverage(samples),
|
||||||
_lastFullTotalEncodeTime(0),
|
|
||||||
_incomingPacket(0),
|
_incomingPacket(0),
|
||||||
_incomingBytes(0),
|
_incomingBytes(0),
|
||||||
_incomingWastedBytes(0),
|
_incomingWastedBytes(0),
|
||||||
_incomingLastSequence(0),
|
_incomingLastSequence(0),
|
||||||
_incomingOutOfOrder(0),
|
|
||||||
_incomingLikelyLost(0),
|
_incomingLikelyLost(0),
|
||||||
|
_incomingRecovered(0),
|
||||||
|
_incomingEarly(0),
|
||||||
|
_incomingLate(0),
|
||||||
|
_incomingReallyLate(0),
|
||||||
|
_incomingPossibleDuplicate(0),
|
||||||
|
_missingSequenceNumbers(),
|
||||||
_incomingFlightTimeAverage(samples),
|
_incomingFlightTimeAverage(samples),
|
||||||
_jurisdictionRoot(NULL)
|
_jurisdictionRoot(NULL)
|
||||||
{
|
{
|
||||||
|
@ -53,8 +65,10 @@ OctreeSceneStats& OctreeSceneStats::operator=(const OctreeSceneStats& other) {
|
||||||
void OctreeSceneStats::copyFromOther(const OctreeSceneStats& other) {
|
void OctreeSceneStats::copyFromOther(const OctreeSceneStats& other) {
|
||||||
_totalEncodeTime = other._totalEncodeTime;
|
_totalEncodeTime = other._totalEncodeTime;
|
||||||
_elapsed = other._elapsed;
|
_elapsed = other._elapsed;
|
||||||
_lastFullTotalEncodeTime = other._lastFullTotalEncodeTime;
|
|
||||||
_lastFullElapsed = other._lastFullElapsed;
|
_lastFullElapsed = other._lastFullElapsed;
|
||||||
|
_lastFullTotalEncodeTime = other._lastFullTotalEncodeTime;
|
||||||
|
_lastFullTotalPackets = other._lastFullTotalPackets;
|
||||||
|
_lastFullTotalBytes = other._lastFullTotalBytes;
|
||||||
_encodeStart = other._encodeStart;
|
_encodeStart = other._encodeStart;
|
||||||
|
|
||||||
_packets = other._packets;
|
_packets = other._packets;
|
||||||
|
@ -134,8 +148,14 @@ void OctreeSceneStats::copyFromOther(const OctreeSceneStats& other) {
|
||||||
_incomingBytes = other._incomingBytes;
|
_incomingBytes = other._incomingBytes;
|
||||||
_incomingWastedBytes = other._incomingWastedBytes;
|
_incomingWastedBytes = other._incomingWastedBytes;
|
||||||
_incomingLastSequence = other._incomingLastSequence;
|
_incomingLastSequence = other._incomingLastSequence;
|
||||||
_incomingOutOfOrder = other._incomingOutOfOrder;
|
|
||||||
_incomingLikelyLost = other._incomingLikelyLost;
|
_incomingLikelyLost = other._incomingLikelyLost;
|
||||||
|
_incomingRecovered = other._incomingRecovered;
|
||||||
|
_incomingEarly = other._incomingEarly;
|
||||||
|
_incomingLate = other._incomingLate;
|
||||||
|
_incomingReallyLate = other._incomingReallyLate;
|
||||||
|
_incomingPossibleDuplicate = other._incomingPossibleDuplicate;
|
||||||
|
|
||||||
|
_missingSequenceNumbers = other._missingSequenceNumbers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -493,12 +513,6 @@ int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int a
|
||||||
|
|
||||||
memcpy(&_isFullScene, sourceBuffer, sizeof(_isFullScene));
|
memcpy(&_isFullScene, sourceBuffer, sizeof(_isFullScene));
|
||||||
sourceBuffer += sizeof(_isFullScene);
|
sourceBuffer += sizeof(_isFullScene);
|
||||||
|
|
||||||
if (_isFullScene) {
|
|
||||||
_lastFullElapsed = _elapsed;
|
|
||||||
_lastFullTotalEncodeTime = _totalEncodeTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&_isMoving, sourceBuffer, sizeof(_isMoving));
|
memcpy(&_isMoving, sourceBuffer, sizeof(_isMoving));
|
||||||
sourceBuffer += sizeof(_isMoving);
|
sourceBuffer += sizeof(_isMoving);
|
||||||
memcpy(&_packets, sourceBuffer, sizeof(_packets));
|
memcpy(&_packets, sourceBuffer, sizeof(_packets));
|
||||||
|
@ -506,6 +520,13 @@ int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int a
|
||||||
memcpy(&_bytes, sourceBuffer, sizeof(_bytes));
|
memcpy(&_bytes, sourceBuffer, sizeof(_bytes));
|
||||||
sourceBuffer += sizeof(_bytes);
|
sourceBuffer += sizeof(_bytes);
|
||||||
|
|
||||||
|
if (_isFullScene) {
|
||||||
|
_lastFullElapsed = _elapsed;
|
||||||
|
_lastFullTotalEncodeTime = _totalEncodeTime;
|
||||||
|
_lastFullTotalPackets = _packets;
|
||||||
|
_lastFullTotalBytes = _bytes;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&_totalInternal, sourceBuffer, sizeof(_totalInternal));
|
memcpy(&_totalInternal, sourceBuffer, sizeof(_totalInternal));
|
||||||
sourceBuffer += sizeof(_totalInternal);
|
sourceBuffer += sizeof(_totalInternal);
|
||||||
memcpy(&_totalLeaves, sourceBuffer, sizeof(_totalLeaves));
|
memcpy(&_totalLeaves, sourceBuffer, sizeof(_totalLeaves));
|
||||||
|
@ -823,18 +844,95 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet,
|
||||||
float flightTimeMsecs = flightTime / USECS_PER_MSEC;
|
float flightTimeMsecs = flightTime / USECS_PER_MSEC;
|
||||||
_incomingFlightTimeAverage.updateAverage(flightTimeMsecs);
|
_incomingFlightTimeAverage.updateAverage(flightTimeMsecs);
|
||||||
|
|
||||||
|
// track out of order and possibly lost packets...
|
||||||
|
const bool wantExtraDebugging = false;
|
||||||
|
if (sequence == _incomingLastSequence) {
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "last packet duplicate got:" << sequence << "_incomingLastSequence:" << _incomingLastSequence;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
OCTREE_PACKET_SEQUENCE expected = _incomingLastSequence+1;
|
||||||
|
if (sequence != expected) {
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "out of order... got:" << sequence << "expected:" << expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the sequence is less than our expected, then this might be a packet
|
||||||
|
// that was delayed and so we should find it in our lostSequence list
|
||||||
|
if (sequence < expected) {
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "this packet is later than expected...";
|
||||||
|
}
|
||||||
|
if (sequence < std::max(0, (expected - MAX_MISSING_SEQUENCE_OLD_AGE))) {
|
||||||
|
_incomingReallyLate++;
|
||||||
|
} else {
|
||||||
|
_incomingLate++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_missingSequenceNumbers.contains(sequence)) {
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "found it in _missingSequenceNumbers";
|
||||||
|
}
|
||||||
|
_missingSequenceNumbers.remove(sequence);
|
||||||
|
_incomingLikelyLost--;
|
||||||
|
_incomingRecovered++;
|
||||||
|
} else {
|
||||||
|
// if we're still in our pruning window, and we didn't find it in our missing list,
|
||||||
|
// than this is really unexpected and can probably only happen if the packet was a
|
||||||
|
// duplicate
|
||||||
|
if (sequence >= std::max(0, (expected - MAX_MISSING_SEQUENCE_OLD_AGE))) {
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "sequence:" << sequence << "WAS NOT found in _missingSequenceNumbers, and not that old... (expected - MAX_MISSING_SEQUENCE_OLD_AGE):" << (expected - MAX_MISSING_SEQUENCE_OLD_AGE);
|
||||||
|
}
|
||||||
|
_incomingPossibleDuplicate++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sequence > expected) {
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "this packet is earlier than expected...";
|
||||||
|
}
|
||||||
|
_incomingEarly++;
|
||||||
|
|
||||||
|
// hmm... so, we either didn't get some packets, or this guy came early...
|
||||||
|
unsigned int missing = sequence - expected;
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << ">>>>>>>> missing gap=" << missing;
|
||||||
|
}
|
||||||
|
_incomingLikelyLost += missing;
|
||||||
|
for(unsigned int missingSequence = expected; missingSequence < sequence; missingSequence++) {
|
||||||
|
_missingSequenceNumbers << missingSequence;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only bump the last sequence if it was greater than our previous last sequence, this will keep us from
|
||||||
|
// accidentally going backwards when an out of order (recovered) packet comes in
|
||||||
|
if (sequence > _incomingLastSequence) {
|
||||||
|
_incomingLastSequence = sequence;
|
||||||
|
}
|
||||||
|
|
||||||
// detect out of order packets
|
// do some garbage collecting on our _missingSequenceNumbers
|
||||||
if (sequence < _incomingLastSequence) {
|
if (_missingSequenceNumbers.size() > MAX_MISSING_SEQUENCE) {
|
||||||
_incomingOutOfOrder++;
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "too many _missingSequenceNumbers:" << _missingSequenceNumbers.size();
|
||||||
|
}
|
||||||
|
foreach(unsigned int missingItem, _missingSequenceNumbers) {
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "checking item:" << missingItem << "is it in need of pruning?";
|
||||||
|
qDebug() << "(_incomingLastSequence - MAX_MISSING_SEQUENCE_OLD_AGE):"
|
||||||
|
<< (_incomingLastSequence - MAX_MISSING_SEQUENCE_OLD_AGE);
|
||||||
|
}
|
||||||
|
if (missingItem <= std::max(0, (_incomingLastSequence - MAX_MISSING_SEQUENCE_OLD_AGE))) {
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "pruning really old missing sequence:" << missingItem;
|
||||||
|
}
|
||||||
|
_missingSequenceNumbers.remove(missingItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// detect likely lost packets
|
|
||||||
OCTREE_PACKET_SEQUENCE expected = _incomingLastSequence+1;
|
|
||||||
if (sequence > expected) {
|
|
||||||
_incomingLikelyLost++;
|
|
||||||
}
|
|
||||||
|
|
||||||
_incomingLastSequence = sequence;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,8 +150,10 @@ public:
|
||||||
unsigned long getTotalEncodeTime() const { return _totalEncodeTime; }
|
unsigned long getTotalEncodeTime() const { return _totalEncodeTime; }
|
||||||
unsigned long getElapsedTime() const { return _elapsed; }
|
unsigned long getElapsedTime() const { return _elapsed; }
|
||||||
|
|
||||||
unsigned long getLastFullTotalEncodeTime() const { return _lastFullTotalEncodeTime; }
|
|
||||||
unsigned long getLastFullElapsedTime() const { return _lastFullElapsed; }
|
unsigned long getLastFullElapsedTime() const { return _lastFullElapsed; }
|
||||||
|
unsigned long getLastFullTotalEncodeTime() const { return _lastFullTotalEncodeTime; }
|
||||||
|
unsigned int getLastFullTotalPackets() const { return _lastFullTotalPackets; }
|
||||||
|
unsigned long getLastFullTotalBytes() const { return _lastFullTotalBytes; }
|
||||||
|
|
||||||
// Used in client implementations to track individual octree packets
|
// Used in client implementations to track individual octree packets
|
||||||
void trackIncomingOctreePacket(const QByteArray& packet, bool wasStatsPacket, int nodeClockSkewUsec);
|
void trackIncomingOctreePacket(const QByteArray& packet, bool wasStatsPacket, int nodeClockSkewUsec);
|
||||||
|
@ -159,8 +161,13 @@ public:
|
||||||
unsigned int getIncomingPackets() const { return _incomingPacket; }
|
unsigned int getIncomingPackets() const { return _incomingPacket; }
|
||||||
unsigned long getIncomingBytes() const { return _incomingBytes; }
|
unsigned long getIncomingBytes() const { return _incomingBytes; }
|
||||||
unsigned long getIncomingWastedBytes() const { return _incomingWastedBytes; }
|
unsigned long getIncomingWastedBytes() const { return _incomingWastedBytes; }
|
||||||
unsigned int getIncomingOutOfOrder() const { return _incomingOutOfOrder; }
|
unsigned int getIncomingOutOfOrder() const { return _incomingLate + _incomingEarly; }
|
||||||
unsigned int getIncomingLikelyLost() const { return _incomingLikelyLost; }
|
unsigned int getIncomingLikelyLost() const { return _incomingLikelyLost; }
|
||||||
|
unsigned int getIncomingRecovered() const { return _incomingRecovered; }
|
||||||
|
unsigned int getIncomingEarly() const { return _incomingEarly; }
|
||||||
|
unsigned int getIncomingLate() const { return _incomingLate; }
|
||||||
|
unsigned int getIncomingReallyLate() const { return _incomingReallyLate; }
|
||||||
|
unsigned int getIncomingPossibleDuplicate() const { return _incomingPossibleDuplicate; }
|
||||||
float getIncomingFlightTimeAverage() { return _incomingFlightTimeAverage.getAverage(); }
|
float getIncomingFlightTimeAverage() { return _incomingFlightTimeAverage.getAverage(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -176,13 +183,16 @@ private:
|
||||||
quint64 _start;
|
quint64 _start;
|
||||||
quint64 _end;
|
quint64 _end;
|
||||||
quint64 _elapsed;
|
quint64 _elapsed;
|
||||||
|
|
||||||
quint64 _lastFullElapsed;
|
quint64 _lastFullElapsed;
|
||||||
|
quint64 _lastFullTotalEncodeTime;
|
||||||
|
unsigned int _lastFullTotalPackets;
|
||||||
|
unsigned long _lastFullTotalBytes;
|
||||||
|
|
||||||
SimpleMovingAverage _elapsedAverage;
|
SimpleMovingAverage _elapsedAverage;
|
||||||
SimpleMovingAverage _bitsPerOctreeAverage;
|
SimpleMovingAverage _bitsPerOctreeAverage;
|
||||||
|
|
||||||
quint64 _totalEncodeTime;
|
quint64 _totalEncodeTime;
|
||||||
quint64 _lastFullTotalEncodeTime;
|
|
||||||
quint64 _encodeStart;
|
quint64 _encodeStart;
|
||||||
|
|
||||||
// scene octree related data
|
// scene octree related data
|
||||||
|
@ -251,9 +261,15 @@ private:
|
||||||
unsigned int _incomingPacket;
|
unsigned int _incomingPacket;
|
||||||
unsigned long _incomingBytes;
|
unsigned long _incomingBytes;
|
||||||
unsigned long _incomingWastedBytes;
|
unsigned long _incomingWastedBytes;
|
||||||
unsigned int _incomingLastSequence;
|
|
||||||
unsigned int _incomingOutOfOrder;
|
uint16_t _incomingLastSequence; /// last incoming sequence number
|
||||||
unsigned int _incomingLikelyLost;
|
unsigned int _incomingLikelyLost; /// count of packets likely lost, may be off by _incomingReallyLate count
|
||||||
|
unsigned int _incomingRecovered; /// packets that were late, and we had in our missing list, we consider recovered
|
||||||
|
unsigned int _incomingEarly; /// out of order earlier than expected
|
||||||
|
unsigned int _incomingLate; /// out of order later than expected
|
||||||
|
unsigned int _incomingReallyLate; /// out of order and later than MAX_MISSING_SEQUENCE_OLD_AGE late
|
||||||
|
unsigned int _incomingPossibleDuplicate; /// out of order possibly a duplicate
|
||||||
|
QSet<unsigned int> _missingSequenceNumbers;
|
||||||
SimpleMovingAverage _incomingFlightTimeAverage;
|
SimpleMovingAverage _incomingFlightTimeAverage;
|
||||||
|
|
||||||
// features related items
|
// features related items
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include "LocalVoxels.h"
|
#include "LocalVoxels.h"
|
||||||
#include "ScriptEngine.h"
|
#include "ScriptEngine.h"
|
||||||
|
|
||||||
const unsigned int VISUAL_DATA_CALLBACK_USECS = (1.0 / 60.0) * 1000 * 1000;
|
|
||||||
|
|
||||||
int ScriptEngine::_scriptNumber = 1;
|
int ScriptEngine::_scriptNumber = 1;
|
||||||
VoxelsScriptingInterface ScriptEngine::_voxelsScriptingInterface;
|
VoxelsScriptingInterface ScriptEngine::_voxelsScriptingInterface;
|
||||||
ParticlesScriptingInterface ScriptEngine::_particlesScriptingInterface;
|
ParticlesScriptingInterface ScriptEngine::_particlesScriptingInterface;
|
||||||
|
@ -54,6 +52,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, co
|
||||||
_avatarIdentityTimer(NULL),
|
_avatarIdentityTimer(NULL),
|
||||||
_avatarBillboardTimer(NULL),
|
_avatarBillboardTimer(NULL),
|
||||||
_timerFunctionMap(),
|
_timerFunctionMap(),
|
||||||
|
_avatarAudioBuffer(NULL),
|
||||||
_controllerScriptingInterface(controllerScriptingInterface),
|
_controllerScriptingInterface(controllerScriptingInterface),
|
||||||
_avatarData(NULL),
|
_avatarData(NULL),
|
||||||
_wantMenuItems(wantMenuItems),
|
_wantMenuItems(wantMenuItems),
|
||||||
|
@ -77,9 +76,6 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, co
|
||||||
_scriptNumber++;
|
_scriptNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptEngine::~ScriptEngine() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptEngine::setIsAvatar(bool isAvatar) {
|
void ScriptEngine::setIsAvatar(bool isAvatar) {
|
||||||
_isAvatar = isAvatar;
|
_isAvatar = isAvatar;
|
||||||
|
|
||||||
|
@ -169,8 +165,8 @@ void ScriptEngine::init() {
|
||||||
_engine.globalObject().setProperty("TREE_SCALE", treeScaleValue);
|
_engine.globalObject().setProperty("TREE_SCALE", treeScaleValue);
|
||||||
|
|
||||||
// let the VoxelPacketSender know how frequently we plan to call it
|
// let the VoxelPacketSender know how frequently we plan to call it
|
||||||
_voxelsScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
|
_voxelsScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(SCRIPT_DATA_CALLBACK_USECS);
|
||||||
_particlesScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
|
_particlesScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(SCRIPT_DATA_CALLBACK_USECS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +224,7 @@ void ScriptEngine::run() {
|
||||||
qint64 lastUpdate = usecTimestampNow();
|
qint64 lastUpdate = usecTimestampNow();
|
||||||
|
|
||||||
while (!_isFinished) {
|
while (!_isFinished) {
|
||||||
int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * VISUAL_DATA_CALLBACK_USECS) - usecTimestampNow();
|
int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * SCRIPT_DATA_CALLBACK_USECS) - usecTimestampNow();
|
||||||
if (usecToSleep > 0) {
|
if (usecToSleep > 0) {
|
||||||
usleep(usecToSleep);
|
usleep(usecToSleep);
|
||||||
}
|
}
|
||||||
|
@ -268,6 +264,21 @@ void ScriptEngine::run() {
|
||||||
avatarPacket.append(_avatarData->toByteArray());
|
avatarPacket.append(_avatarData->toByteArray());
|
||||||
|
|
||||||
nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer);
|
nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer);
|
||||||
|
|
||||||
|
if (_avatarAudioBuffer && _numAvatarAudioBufferSamples > 0) {
|
||||||
|
// if have an avatar audio stream then send it out to our audio-mixer
|
||||||
|
QByteArray audioPacket = byteArrayWithPopulatedHeader(PacketTypeMicrophoneAudioNoEcho);
|
||||||
|
QDataStream packetStream(&audioPacket, QIODevice::Append);
|
||||||
|
|
||||||
|
// use the orientation and position of this avatar for the source of this audio
|
||||||
|
packetStream.writeRawData(reinterpret_cast<const char*>(&_avatarData->getPosition()), sizeof(glm::vec3));
|
||||||
|
glm::quat headOrientation = _avatarData->getHeadOrientation();
|
||||||
|
packetStream.writeRawData(reinterpret_cast<const char*>(&headOrientation), sizeof(glm::quat));
|
||||||
|
packetStream.writeRawData(reinterpret_cast<const char*>(_avatarAudioBuffer),
|
||||||
|
_numAvatarAudioBufferSamples * sizeof(int16_t));
|
||||||
|
|
||||||
|
nodeList->broadcastToNodes(audioPacket, NodeSet() << NodeType::AudioMixer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 now = usecTimestampNow();
|
qint64 now = usecTimestampNow();
|
||||||
|
|
|
@ -20,14 +20,16 @@
|
||||||
|
|
||||||
#include <AvatarData.h>
|
#include <AvatarData.h>
|
||||||
|
|
||||||
class ParticlesScriptingInterface;
|
|
||||||
|
|
||||||
#include "AbstractControllerScriptingInterface.h"
|
#include "AbstractControllerScriptingInterface.h"
|
||||||
#include "Quat.h"
|
#include "Quat.h"
|
||||||
#include "Vec3.h"
|
#include "Vec3.h"
|
||||||
|
|
||||||
|
class ParticlesScriptingInterface;
|
||||||
|
|
||||||
const QString NO_SCRIPT("");
|
const QString NO_SCRIPT("");
|
||||||
|
|
||||||
|
const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 1000) + 0.5);
|
||||||
|
|
||||||
class ScriptEngine : public QObject {
|
class ScriptEngine : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -35,8 +37,6 @@ public:
|
||||||
const QString& scriptMenuName = QString(""),
|
const QString& scriptMenuName = QString(""),
|
||||||
AbstractControllerScriptingInterface* controllerScriptingInterface = NULL);
|
AbstractControllerScriptingInterface* controllerScriptingInterface = NULL);
|
||||||
|
|
||||||
~ScriptEngine();
|
|
||||||
|
|
||||||
/// Access the VoxelsScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
|
/// Access the VoxelsScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
|
||||||
static VoxelsScriptingInterface* getVoxelsScriptingInterface() { return &_voxelsScriptingInterface; }
|
static VoxelsScriptingInterface* getVoxelsScriptingInterface() { return &_voxelsScriptingInterface; }
|
||||||
|
|
||||||
|
@ -56,6 +56,11 @@ public:
|
||||||
|
|
||||||
void setAvatarData(AvatarData* avatarData, const QString& objectName);
|
void setAvatarData(AvatarData* avatarData, const QString& objectName);
|
||||||
|
|
||||||
|
void setAvatarAudioBuffer(int16_t* avatarAudioBuffer) { _avatarAudioBuffer = avatarAudioBuffer; }
|
||||||
|
bool sendsAvatarAudioStream() const { return (bool) _avatarAudioBuffer; }
|
||||||
|
void setNumAvatarAudioBufferSamples(int numAvatarAudioBufferSamples)
|
||||||
|
{ _numAvatarAudioBufferSamples = numAvatarAudioBufferSamples; }
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void run(); /// runs continuously until Agent.stop() is called
|
void run(); /// runs continuously until Agent.stop() is called
|
||||||
void evaluate(); /// initializes the engine, and evaluates the script, but then returns control to caller
|
void evaluate(); /// initializes the engine, and evaluates the script, but then returns control to caller
|
||||||
|
@ -86,6 +91,8 @@ protected:
|
||||||
QTimer* _avatarIdentityTimer;
|
QTimer* _avatarIdentityTimer;
|
||||||
QTimer* _avatarBillboardTimer;
|
QTimer* _avatarBillboardTimer;
|
||||||
QHash<QTimer*, QScriptValue> _timerFunctionMap;
|
QHash<QTimer*, QScriptValue> _timerFunctionMap;
|
||||||
|
int16_t* _avatarAudioBuffer;
|
||||||
|
int _numAvatarAudioBufferSamples;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sendAvatarIdentityPacket();
|
void sendAvatarIdentityPacket();
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <glm/gtc/noise.hpp>
|
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QRgb>
|
#include <QRgb>
|
||||||
|
|
Loading…
Reference in a new issue