mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 15:50:37 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into shared_and_weak_pointers
This commit is contained in:
commit
25a859f95e
18 changed files with 756 additions and 585 deletions
|
@ -278,6 +278,7 @@ void DomainServer::createScriptedAssignmentsFromArray(const QJsonArray &configAr
|
|||
qDebug() << "Adding scripted assignment to queue -" << *scriptAssignment;
|
||||
qDebug() << "URL for script is" << assignmentURL;
|
||||
|
||||
// scripts passed on CL or via JSON are static - so they are added back to the queue if the node dies
|
||||
_assignmentQueue.enqueue(SharedAssignmentPointer(scriptAssignment));
|
||||
}
|
||||
}
|
||||
|
@ -343,7 +344,6 @@ const NodeSet STATICALLY_ASSIGNED_NODES = NodeSet() << NodeType::AudioMixer
|
|||
<< NodeType::AvatarMixer << NodeType::VoxelServer << NodeType::ParticleServer
|
||||
<< NodeType::MetavoxelServer;
|
||||
|
||||
|
||||
void DomainServer::addNodeToNodeListAndConfirmConnection(const QByteArray& packet, const HifiSockAddr& senderSockAddr) {
|
||||
|
||||
NodeType_t nodeType;
|
||||
|
@ -352,19 +352,24 @@ void DomainServer::addNodeToNodeListAndConfirmConnection(const QByteArray& packe
|
|||
int numPreInterestBytes = parseNodeDataFromByteArray(nodeType, publicSockAddr, localSockAddr, packet, senderSockAddr);
|
||||
|
||||
QUuid assignmentUUID = uuidFromPacketHeader(packet);
|
||||
SharedAssignmentPointer matchingAssignment;
|
||||
bool isStaticAssignment = _staticAssignmentHash.contains(assignmentUUID);
|
||||
SharedAssignmentPointer matchingAssignment = SharedAssignmentPointer();
|
||||
|
||||
if (!assignmentUUID.isNull() && (matchingAssignment = matchingStaticAssignmentForCheckIn(assignmentUUID, nodeType))
|
||||
&& matchingAssignment) {
|
||||
// this is an assigned node, make sure the UUID sent is for an assignment we're actually trying to give out
|
||||
if (isStaticAssignment) {
|
||||
// this is a static assignment, make sure the UUID sent is for an assignment we're actually trying to give out
|
||||
matchingAssignment = matchingQueuedAssignmentForCheckIn(assignmentUUID, nodeType);
|
||||
|
||||
if (matchingAssignment) {
|
||||
// remove the matching assignment from the assignment queue so we don't take the next check in
|
||||
// (if it exists)
|
||||
removeMatchingAssignmentFromQueue(matchingAssignment);
|
||||
}
|
||||
} else {
|
||||
assignmentUUID = QUuid();
|
||||
}
|
||||
|
||||
// make sure this was either not a static assignment or it was and we had a matching one in teh queue
|
||||
if ((!isStaticAssignment && !STATICALLY_ASSIGNED_NODES.contains(nodeType)) || (isStaticAssignment && matchingAssignment)) {
|
||||
// create a new session UUID for this node
|
||||
QUuid nodeUUID = QUuid::createUuid();
|
||||
|
||||
|
@ -381,6 +386,7 @@ void DomainServer::addNodeToNodeListAndConfirmConnection(const QByteArray& packe
|
|||
// reply back to the user with a PacketTypeDomainList
|
||||
sendDomainListToNode(newNode, senderSockAddr, nodeInterestListFromPacket(packet, numPreInterestBytes));
|
||||
}
|
||||
}
|
||||
|
||||
int DomainServer::parseNodeDataFromByteArray(NodeType_t& nodeType, HifiSockAddr& publicSockAddr,
|
||||
HifiSockAddr& localSockAddr, const QByteArray& packet,
|
||||
|
@ -740,6 +746,16 @@ QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
|
|||
return nodeJson;
|
||||
}
|
||||
|
||||
const char ASSIGNMENT_SCRIPT_HOST_LOCATION[] = "resources/web/assignment";
|
||||
|
||||
QString pathForAssignmentScript(const QUuid& assignmentUUID) {
|
||||
QString newPath(ASSIGNMENT_SCRIPT_HOST_LOCATION);
|
||||
newPath += "/";
|
||||
// append the UUID for this script as the new filename, remove the curly braces
|
||||
newPath += uuidStringWithoutCurlyBraces(assignmentUUID);
|
||||
return newPath;
|
||||
}
|
||||
|
||||
bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url) {
|
||||
const QString JSON_MIME_TYPE = "application/json";
|
||||
|
||||
|
@ -870,17 +886,13 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
|||
assignmentPool = QString(assignmentPoolValue);
|
||||
}
|
||||
|
||||
const char ASSIGNMENT_SCRIPT_HOST_LOCATION[] = "resources/web/assignment";
|
||||
|
||||
for (int i = 0; i < numInstances; i++) {
|
||||
|
||||
// create an assignment for this saved script
|
||||
Assignment* scriptAssignment = new Assignment(Assignment::CreateCommand, Assignment::AgentType, assignmentPool);
|
||||
|
||||
QString newPath(ASSIGNMENT_SCRIPT_HOST_LOCATION);
|
||||
newPath += "/";
|
||||
// append the UUID for this script as the new filename, remove the curly braces
|
||||
newPath += uuidStringWithoutCurlyBraces(scriptAssignment->getUUID());
|
||||
QString newPath = pathForAssignmentScript(scriptAssignment->getUUID());
|
||||
|
||||
// create a file with the GUID of the assignment in the script host location
|
||||
QFile scriptFile(newPath);
|
||||
|
@ -945,6 +957,11 @@ void DomainServer::refreshStaticAssignmentAndAddToQueue(SharedAssignmentPointer&
|
|||
qDebug() << "Reset UUID for assignment -" << *assignment.data() << "- and added to queue. Old UUID was"
|
||||
<< uuidStringWithoutCurlyBraces(oldUUID);
|
||||
|
||||
if (assignment->getType() == Assignment::AgentType && assignment->getPayload().isEmpty()) {
|
||||
// if this was an Agent without a script URL, we need to rename the old file so it can be retrieved at the new UUID
|
||||
QFile::rename(pathForAssignmentScript(oldUUID), pathForAssignmentScript(assignment->getUUID()));
|
||||
}
|
||||
|
||||
// add the static assignment back under the right UUID, and to the queue
|
||||
_staticAssignmentHash.insert(assignment->getUUID(), assignment);
|
||||
|
||||
|
@ -992,7 +1009,7 @@ void DomainServer::nodeKilled(SharedNodePointer node) {
|
|||
}
|
||||
}
|
||||
|
||||
SharedAssignmentPointer DomainServer::matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NodeType_t nodeType) {
|
||||
SharedAssignmentPointer DomainServer::matchingQueuedAssignmentForCheckIn(const QUuid& checkInUUID, NodeType_t nodeType) {
|
||||
QQueue<SharedAssignmentPointer>::iterator i = _assignmentQueue.begin();
|
||||
|
||||
while (i != _assignmentQueue.end()) {
|
||||
|
@ -1020,21 +1037,20 @@ SharedAssignmentPointer DomainServer::deployableAssignmentForRequest(const Assig
|
|||
|
||||
if ((requestIsAllTypes || assignmentTypesMatch) && (nietherHasPool || assignmentPoolsMatch)) {
|
||||
|
||||
if (assignment->getType() == Assignment::AgentType) {
|
||||
// if there is more than one instance to send out, simply decrease the number of instances
|
||||
return _assignmentQueue.takeAt(sharedAssignment - _assignmentQueue.begin());
|
||||
} else {
|
||||
// remove the assignment from the queue
|
||||
SharedAssignmentPointer deployableAssignment = _assignmentQueue.takeAt(sharedAssignment
|
||||
- _assignmentQueue.begin());
|
||||
|
||||
if (deployableAssignment->getType() != Assignment::AgentType
|
||||
|| _staticAssignmentHash.contains(deployableAssignment->getUUID())) {
|
||||
// this is a static assignment
|
||||
// until we get a check-in from that GUID
|
||||
// put assignment back in queue but stick it at the back so the others have a chance to go out
|
||||
_assignmentQueue.enqueue(deployableAssignment);
|
||||
}
|
||||
|
||||
// stop looping, we've handed out an assignment
|
||||
return deployableAssignment;
|
||||
}
|
||||
} else {
|
||||
// push forward the iterator to check the next assignment
|
||||
++sharedAssignment;
|
||||
|
|
|
@ -70,7 +70,7 @@ private:
|
|||
void createStaticAssignmentsForType(Assignment::Type type, const QJsonArray& configArray);
|
||||
void populateDefaultStaticAssignmentsExcludingTypes(const QSet<Assignment::Type>& excludedTypes);
|
||||
|
||||
SharedAssignmentPointer matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NodeType_t nodeType);
|
||||
SharedAssignmentPointer matchingQueuedAssignmentForCheckIn(const QUuid& checkInUUID, NodeType_t nodeType);
|
||||
SharedAssignmentPointer deployableAssignmentForRequest(const Assignment& requestAssignment);
|
||||
void removeMatchingAssignmentFromQueue(const SharedAssignmentPointer& removableAssignment);
|
||||
void refreshStaticAssignmentAndAddToQueue(SharedAssignmentPointer& assignment);
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var editToolsOn = true; // starts out off
|
||||
|
||||
var windowDimensions = Controller.getViewportDimensions();
|
||||
var WORLD_SCALE = Voxels.getTreeScale();
|
||||
|
||||
var NEW_VOXEL_SIZE = 1.0;
|
||||
var NEW_VOXEL_DISTANCE_FROM_CAMERA = 3.0;
|
||||
|
@ -62,7 +65,7 @@ colors[6] = { red: 211, green: 115, blue: 0 };
|
|||
colors[7] = { red: 48, green: 116, blue: 119 };
|
||||
colors[8] = { red: 31, green: 64, blue: 64 };
|
||||
var numColors = 9;
|
||||
var whichColor = -1; // Starting color is 'Copy' mode
|
||||
var whichColor = 0; // Starting color is 'Copy' mode
|
||||
|
||||
// Create sounds for for every script actions that require one
|
||||
var audioOptions = new AudioInjectionOptions();
|
||||
|
@ -149,9 +152,6 @@ colorInheritSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/
|
|||
colorInheritSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Color+Inherit/Inherit+B.raw");
|
||||
colorInheritSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Color+Inherit/Inherit+C.raw");
|
||||
|
||||
|
||||
var editToolsOn = true; // starts out off
|
||||
|
||||
// previewAsVoxel - by default, we will preview adds/deletes/recolors as just 4 lines on the intersecting face. But if you
|
||||
// the preview to show a full voxel then set this to true and the voxel will be displayed for voxel editing
|
||||
var previewAsVoxel = false;
|
||||
|
@ -204,8 +204,8 @@ var linePreviewRight = Overlays.addOverlay("line3d", {
|
|||
|
||||
|
||||
// these will be used below
|
||||
var sliderWidth = 154;
|
||||
var sliderHeight = 37;
|
||||
var scaleSelectorWidth = 144;
|
||||
var scaleSelectorHeight = 37;
|
||||
|
||||
// These will be our "overlay IDs"
|
||||
var swatches = new Array();
|
||||
|
@ -213,7 +213,7 @@ var swatchExtraPadding = 5;
|
|||
var swatchHeight = 37;
|
||||
var swatchWidth = 27;
|
||||
var swatchesWidth = swatchWidth * numColors + numColors + swatchExtraPadding * 2;
|
||||
var swatchesX = (windowDimensions.x - (swatchesWidth + sliderWidth)) / 2;
|
||||
var swatchesX = (windowDimensions.x - (swatchesWidth + scaleSelectorWidth)) / 2;
|
||||
var swatchesY = windowDimensions.y - swatchHeight + 1;
|
||||
|
||||
var toolIconUrl = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/";
|
||||
|
@ -270,7 +270,7 @@ var voxelTool = Overlays.addOverlay("image", {
|
|||
x: 0, y: 0, width: toolWidth, height: toolHeight,
|
||||
subImage: { x: 0, y: toolHeight, width: toolWidth, height: toolHeight },
|
||||
imageURL: toolIconUrl + "voxel-tool.svg",
|
||||
visible: false,
|
||||
visible: editToolsOn,
|
||||
alpha: 0.9
|
||||
});
|
||||
|
||||
|
@ -278,7 +278,7 @@ var recolorTool = Overlays.addOverlay("image", {
|
|||
x: 0, y: 0, width: toolWidth, height: toolHeight,
|
||||
subImage: { x: 0, y: toolHeight, width: toolWidth, height: toolHeight },
|
||||
imageURL: toolIconUrl + "paint-tool.svg",
|
||||
visible: false,
|
||||
visible: editToolsOn,
|
||||
alpha: 0.9
|
||||
});
|
||||
|
||||
|
@ -286,58 +286,154 @@ var eyedropperTool = Overlays.addOverlay("image", {
|
|||
x: 0, y: 0, width: toolWidth, height: toolHeight,
|
||||
subImage: { x: 0, y: toolHeight, width: toolWidth, height: toolHeight },
|
||||
imageURL: toolIconUrl + "eyedropper-tool.svg",
|
||||
visible: false,
|
||||
visible: editToolsOn,
|
||||
alpha: 0.9
|
||||
});
|
||||
|
||||
// This will create a couple of image overlays that make a "slider", we will demonstrate how to trap mouse messages to
|
||||
// move the slider
|
||||
|
||||
// see above...
|
||||
//var sliderWidth = 158;
|
||||
//var sliderHeight = 35;
|
||||
var copyScale = true;
|
||||
function ScaleSelector() {
|
||||
this.x = swatchesX + swatchesWidth;
|
||||
this.y = swatchesY;
|
||||
this.width = scaleSelectorWidth;
|
||||
this.height = scaleSelectorHeight;
|
||||
|
||||
var sliderOffsetX = 17;
|
||||
var sliderX = swatchesX - swatchWidth - sliderOffsetX;
|
||||
var sliderY = windowDimensions.y - sliderHeight + 1;
|
||||
var slider = Overlays.addOverlay("image", {
|
||||
// alternate form of expressing bounds
|
||||
bounds: { x: sliderX, y: sliderY, width: sliderWidth, height: sliderHeight},
|
||||
imageURL: toolIconUrl + "voxel-size-slider-bg.svg",
|
||||
alpha: 1,
|
||||
this.displayPower = false;
|
||||
this.scale = 1.0;
|
||||
this.power = 0;
|
||||
|
||||
this.FIRST_PART = this.width * 40.0 / 100.0;
|
||||
this.SECOND_PART = this.width * 37.0 / 100.0;
|
||||
|
||||
this.buttonsOverlay = Overlays.addOverlay("image", {
|
||||
x: this.x, y: this.y,
|
||||
width: this.width, height: this.height,
|
||||
//subImage: { x: 0, y: toolHeight, width: toolWidth, height: toolHeight },
|
||||
imageURL: toolIconUrl + "voxel-size-selector.svg",
|
||||
alpha: 0.9,
|
||||
visible: editToolsOn
|
||||
});
|
||||
this.textOverlay = Overlays.addOverlay("text", {
|
||||
x: this.x + this.FIRST_PART, y: this.y,
|
||||
width: this.SECOND_PART, height: this.height,
|
||||
topMargin: 13,
|
||||
text: this.scale.toString(),
|
||||
alpha: 0.0,
|
||||
visible: editToolsOn
|
||||
});
|
||||
this.powerOverlay = Overlays.addOverlay("text", {
|
||||
x: this.x + this.FIRST_PART, y: this.y,
|
||||
width: this.SECOND_PART, height: this.height,
|
||||
leftMargin: 28,
|
||||
text: this.power.toString(),
|
||||
alpha: 0.0,
|
||||
visible: false
|
||||
});
|
||||
this.setScale = function(scale) {
|
||||
this.scale = scale;
|
||||
this.power = Math.floor(Math.log(scale));
|
||||
rescaleImport();
|
||||
}
|
||||
|
||||
// The slider is handled in the mouse event callbacks.
|
||||
var isMovingSlider = false;
|
||||
var thumbClickOffsetX = 0;
|
||||
this.show = function(doShow) {
|
||||
Overlays.editOverlay(this.buttonsOverlay, {visible: doShow});
|
||||
Overlays.editOverlay(this.textOverlay, {visible: doShow});
|
||||
Overlays.editOverlay(this.powerOverlay, {visible: doShow && this.displayPower});
|
||||
}
|
||||
|
||||
// This is the thumb of our slider
|
||||
var minThumbX = 20; // relative to the x of the slider
|
||||
var maxThumbX = minThumbX + 90;
|
||||
var thumbExtents = maxThumbX - minThumbX;
|
||||
var thumbX = (minThumbX + maxThumbX) / 2;
|
||||
var thumbOffsetY = 11;
|
||||
var thumbY = sliderY + thumbOffsetY;
|
||||
var thumb = Overlays.addOverlay("image", {
|
||||
x: sliderX + thumbX,
|
||||
y: thumbY,
|
||||
width: 17,
|
||||
height: 17,
|
||||
imageURL: toolIconUrl + "voxel-size-slider-handle.svg",
|
||||
alpha: 1,
|
||||
this.move = function() {
|
||||
this.x = swatchesX + swatchesWidth;
|
||||
this.y = swatchesY;
|
||||
|
||||
Overlays.editOverlay(this.buttonsOverlay, {
|
||||
x: this.x, y: this.y,
|
||||
});
|
||||
Overlays.editOverlay(this.textOverlay, {
|
||||
x: this.x + this.FIRST_PART, y: this.y,
|
||||
});
|
||||
Overlays.editOverlay(this.powerOverlay, {
|
||||
x: this.x + this.FIRST_PART, y: this.y,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
this.switchDisplay = function() {
|
||||
this.displayPower = !this.displayPower;
|
||||
|
||||
if (this.displayPower) {
|
||||
Overlays.editOverlay(this.textOverlay, {
|
||||
leftMargin: 18,
|
||||
text: "2"
|
||||
});
|
||||
Overlays.editOverlay(this.powerOverlay, {
|
||||
text: this.power.toString(),
|
||||
visible: editToolsOn
|
||||
});
|
||||
} else {
|
||||
Overlays.editOverlay(this.textOverlay, {
|
||||
leftMargin: 13,
|
||||
text: this.scale.toString()
|
||||
});
|
||||
Overlays.editOverlay(this.powerOverlay, {
|
||||
visible: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
this.update = function() {
|
||||
if (this.displayPower) {
|
||||
Overlays.editOverlay(this.powerOverlay, {text: this.power.toString()});
|
||||
} else {
|
||||
Overlays.editOverlay(this.textOverlay, {text: this.scale.toString()});
|
||||
}
|
||||
}
|
||||
|
||||
var pointerVoxelScaleSteps = 8; // the number of slider position steps
|
||||
var pointerVoxelScaleOriginStep = 8; // the position of slider for the 1 meter size voxel
|
||||
var pointerVoxelScaleMin = Math.pow(2, (1-pointerVoxelScaleOriginStep));
|
||||
var pointerVoxelScaleMax = Math.pow(2, (pointerVoxelScaleSteps-pointerVoxelScaleOriginStep));
|
||||
var thumbDeltaPerStep = thumbExtents / (pointerVoxelScaleSteps - 1);
|
||||
this.incrementScale = function() {
|
||||
copyScale = false;
|
||||
if (this.power < 13) {
|
||||
++this.power;
|
||||
this.scale *= 2.0;
|
||||
this.update();
|
||||
rescaleImport();
|
||||
resizeVoxelSound.play(voxelSizePlus);
|
||||
}
|
||||
}
|
||||
|
||||
this.decrementScale = function() {
|
||||
copyScale = false;
|
||||
if (-4 < this.power) {
|
||||
--this.power;
|
||||
this.scale /= 2.0;
|
||||
this.update();
|
||||
rescaleImport();
|
||||
resizeVoxelSound.play(voxelSizePlus);
|
||||
}
|
||||
}
|
||||
|
||||
this.clicked = function(x, y) {
|
||||
if (this.x < x && x < this.x + this.width &&
|
||||
this.y < y && y < this.y + this.height) {
|
||||
|
||||
if (x < this.x + this.FIRST_PART) {
|
||||
this.decrementScale();
|
||||
} else if (x < this.x + this.FIRST_PART + this.SECOND_PART) {
|
||||
this.switchDisplay();
|
||||
} else {
|
||||
this.incrementScale();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
this.cleanup = function() {
|
||||
Overlays.deleteOverlay(this.buttonsOverlay);
|
||||
Overlays.deleteOverlay(this.textOverlay);
|
||||
Overlays.deleteOverlay(this.powerOverlay);
|
||||
}
|
||||
|
||||
}
|
||||
var scaleSelector = new ScaleSelector();
|
||||
|
||||
|
||||
///////////////////////////////////// IMPORT MODULE ///////////////////////////////
|
||||
|
@ -345,9 +441,12 @@ var thumbDeltaPerStep = thumbExtents / (pointerVoxelScaleSteps - 1);
|
|||
var importTree;
|
||||
var importPreview;
|
||||
var importBoundaries;
|
||||
var xImportGuide;
|
||||
var yImportGuide;
|
||||
var zImportGuide;
|
||||
var isImporting;
|
||||
var importPosition;
|
||||
var importScale;
|
||||
var importDistance;
|
||||
|
||||
function initImport() {
|
||||
importPreview = Overlays.addOverlay("localvoxels", {
|
||||
|
@ -358,31 +457,49 @@ function initImport() {
|
|||
});
|
||||
importBoundaries = Overlays.addOverlay("cube", {
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
scale: 1,
|
||||
size: 1,
|
||||
color: { red: 128, blue: 128, green: 128 },
|
||||
lineWIdth: 4,
|
||||
solid: false,
|
||||
visible: false
|
||||
})
|
||||
});
|
||||
|
||||
xImportGuide = Overlays.addOverlay("line3d", {
|
||||
position: { x: 0, y: 0, z: 0},
|
||||
end: { x: 0, y: 0, z: 0},
|
||||
color: { red: 255, green: 0, blue: 0},
|
||||
alpha: 1,
|
||||
visible: false,
|
||||
lineWidth: previewLineWidth
|
||||
});
|
||||
yImportGuide = Overlays.addOverlay("line3d", {
|
||||
position: { x: 0, y: 0, z: 0},
|
||||
end: { x: 0, y: 0, z: 0},
|
||||
color: { red: 0, green: 255, blue: 0},
|
||||
alpha: 1,
|
||||
visible: false,
|
||||
lineWidth: previewLineWidth
|
||||
});
|
||||
zImportGuide = Overlays.addOverlay("line3d", {
|
||||
position: { x: 0, y: 0, z: 0},
|
||||
end: { x: 0, y: 0, z: 0},
|
||||
color: { red: 0, green: 0, blue: 255},
|
||||
alpha: 1,
|
||||
visible: false,
|
||||
lineWidth: previewLineWidth
|
||||
});
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
isImporting = Clipboard.importVoxels();
|
||||
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 }
|
||||
|
@ -390,17 +507,40 @@ function moveImport(position) {
|
|||
Overlays.editOverlay(importBoundaries, {
|
||||
position: { x: importPosition.x, y: importPosition.y, z: importPosition.z }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Overlays.editOverlay(xImportGuide, {
|
||||
position: { x: importPosition.x, y: 0, z: importPosition.z },
|
||||
end: { x: importPosition.x + scaleSelector.scale, y: 0, z: importPosition.z }
|
||||
});
|
||||
Overlays.editOverlay(yImportGuide, {
|
||||
position: { x: importPosition.x, y: importPosition.y, z: importPosition.z },
|
||||
end: { x: importPosition.x, y: 0, z: importPosition.z }
|
||||
});
|
||||
Overlays.editOverlay(zImportGuide, {
|
||||
position: { x: importPosition.x, y: 0, z: importPosition.z },
|
||||
end: { x: importPosition.x, y: 0, z: importPosition.z + scaleSelector.scale }
|
||||
});
|
||||
rescaleImport();
|
||||
}
|
||||
|
||||
function rescaleImport(scale) {
|
||||
if (0 < scale) {
|
||||
importScale = scale;
|
||||
function rescaleImport() {
|
||||
if (0 < scaleSelector.scale) {
|
||||
Overlays.editOverlay(importPreview, {
|
||||
scale: importScale
|
||||
scale: scaleSelector.scale
|
||||
});
|
||||
Overlays.editOverlay(importBoundaries, {
|
||||
scale: importScale
|
||||
size: scaleSelector.scale
|
||||
});
|
||||
|
||||
Overlays.editOverlay(xImportGuide, {
|
||||
end: { x: importPosition.x + scaleSelector.scale, y: 0, z: importPosition.z }
|
||||
});
|
||||
Overlays.editOverlay(yImportGuide, {
|
||||
end: { x: importPosition.x, y: 0, z: importPosition.z }
|
||||
});
|
||||
Overlays.editOverlay(zImportGuide, {
|
||||
end: { x: importPosition.x, y: 0, z: importPosition.z + scaleSelector.scale }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -412,11 +552,21 @@ function showImport(doShow) {
|
|||
Overlays.editOverlay(importBoundaries, {
|
||||
visible: doShow
|
||||
});
|
||||
|
||||
Overlays.editOverlay(xImportGuide, {
|
||||
visible: doShow
|
||||
});
|
||||
Overlays.editOverlay(yImportGuide, {
|
||||
visible: doShow
|
||||
});
|
||||
Overlays.editOverlay(zImportGuide, {
|
||||
visible: doShow
|
||||
});
|
||||
}
|
||||
|
||||
function placeImport() {
|
||||
if (isImporting) {
|
||||
Clipboard.pasteVoxel(importPosition.x, importPosition.y, importPosition.z, importScale);
|
||||
Clipboard.pasteVoxel(importPosition.x, importPosition.y, importPosition.z, scaleSelector.scale);
|
||||
isImporting = false;
|
||||
}
|
||||
}
|
||||
|
@ -431,9 +581,11 @@ function cancelImport() {
|
|||
function cleanupImport() {
|
||||
Overlays.deleteOverlay(importPreview);
|
||||
Overlays.deleteOverlay(importBoundaries);
|
||||
Overlays.deleteOverlay(xImportGuide);
|
||||
Overlays.deleteOverlay(yImportGuide);
|
||||
Overlays.deleteOverlay(zImportGuide);
|
||||
isImporting = false;
|
||||
importPostion = { x: 0, y: 0, z: 0 };
|
||||
importScale = 0;
|
||||
}
|
||||
/////////////////////////////////// END IMPORT MODULE /////////////////////////////
|
||||
initImport();
|
||||
|
@ -442,49 +594,6 @@ if (editToolsOn) {
|
|||
moveTools();
|
||||
}
|
||||
|
||||
|
||||
function calcThumbFromScale(scale) {
|
||||
var scaleLog = Math.log(scale)/Math.log(2);
|
||||
var thumbStep = scaleLog + pointerVoxelScaleOriginStep;
|
||||
if (thumbStep < 1) {
|
||||
thumbStep = 1;
|
||||
}
|
||||
if (thumbStep > pointerVoxelScaleSteps) {
|
||||
thumbStep = pointerVoxelScaleSteps;
|
||||
}
|
||||
var oldThumbX = thumbX;
|
||||
thumbX = (thumbDeltaPerStep * (thumbStep - 1)) + minThumbX;
|
||||
Overlays.editOverlay(thumb, { x: thumbX + sliderX } );
|
||||
|
||||
if (thumbX > oldThumbX) {
|
||||
resizeVoxelSound.play(voxelSizePlus);
|
||||
print("Plus");
|
||||
} else if (thumbX < oldThumbX) {
|
||||
resizeVoxelSound.play(voxelSizeMinus);
|
||||
print("Minus");
|
||||
}
|
||||
}
|
||||
|
||||
function calcScaleFromThumb(newThumbX) {
|
||||
// newThumbX is the pixel location relative to start of slider,
|
||||
// we need to figure out the actual offset in the allowed slider area
|
||||
thumbAt = newThumbX - minThumbX;
|
||||
thumbStep = Math.floor((thumbAt/ thumbExtents) * (pointerVoxelScaleSteps-1)) + 1;
|
||||
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...
|
||||
calcThumbFromScale(pointerVoxelScale);
|
||||
|
||||
// if the user moved the thumb, then they are fixing the voxel scale
|
||||
pointerVoxelScaleSet = true;
|
||||
}
|
||||
|
||||
function setAudioPosition() {
|
||||
var position = MyAvatar.position;
|
||||
var forwardVector = Quat.getFront(MyAvatar.orientation);
|
||||
|
@ -493,7 +602,7 @@ function setAudioPosition() {
|
|||
|
||||
function getNewPasteVoxel(pickRay) {
|
||||
|
||||
var voxelSize = MIN_PASTE_VOXEL_SCALE + (MAX_PASTE_VOXEL_SCALE - MIN_PASTE_VOXEL_SCALE) * pointerVoxelScale - 1;
|
||||
var voxelSize = scaleSelector.scale;
|
||||
var origin = { x: pickRay.direction.x, y: pickRay.direction.y, z: pickRay.direction.z };
|
||||
|
||||
origin.x += pickRay.origin.x;
|
||||
|
@ -542,13 +651,7 @@ function calculateVoxelFromIntersection(intersection, operation) {
|
|||
+ intersection.intersection.y + ", " + intersection.intersection.z);
|
||||
}
|
||||
|
||||
var voxelSize;
|
||||
if (pointerVoxelScaleSet) {
|
||||
voxelSize = pointerVoxelScale;
|
||||
} else {
|
||||
voxelSize = intersection.voxel.s;
|
||||
}
|
||||
|
||||
var voxelSize = scaleSelector.scale;
|
||||
var x;
|
||||
var y;
|
||||
var z;
|
||||
|
@ -670,21 +773,9 @@ function showPreviewVoxel() {
|
|||
var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY);
|
||||
var intersection = Voxels.findRayIntersection(pickRay);
|
||||
|
||||
// if the user hasn't updated the
|
||||
if (!pointerVoxelScaleSet) {
|
||||
calcThumbFromScale(intersection.voxel.s);
|
||||
}
|
||||
|
||||
if (whichColor == -1) {
|
||||
// Copy mode - use clicked voxel color
|
||||
voxelColor = { red: intersection.voxel.red,
|
||||
green: intersection.voxel.green,
|
||||
blue: intersection.voxel.blue };
|
||||
} else {
|
||||
voxelColor = { red: colors[whichColor].red,
|
||||
green: colors[whichColor].green,
|
||||
blue: colors[whichColor].blue };
|
||||
}
|
||||
|
||||
var guidePosition;
|
||||
if (trackAsRecolor || recolorToolSelected || trackAsEyedropper || eyedropperToolSelected) {
|
||||
|
@ -734,18 +825,19 @@ function showPreviewLines() {
|
|||
var intersection = Voxels.findRayIntersection(pickRay);
|
||||
|
||||
if (intersection.intersects) {
|
||||
|
||||
// if the user hasn't updated the
|
||||
if (!pointerVoxelScaleSet) {
|
||||
calcThumbFromScale(intersection.voxel.s);
|
||||
}
|
||||
|
||||
resultVoxel = calculateVoxelFromIntersection(intersection,"");
|
||||
Overlays.editOverlay(voxelPreview, { visible: false });
|
||||
Overlays.editOverlay(linePreviewTop, { position: resultVoxel.topLeft, end: resultVoxel.topRight, visible: true });
|
||||
Overlays.editOverlay(linePreviewBottom, { position: resultVoxel.bottomLeft, end: resultVoxel.bottomRight, visible: true });
|
||||
Overlays.editOverlay(linePreviewLeft, { position: resultVoxel.topLeft, end: resultVoxel.bottomLeft, visible: true });
|
||||
Overlays.editOverlay(linePreviewRight, { position: resultVoxel.topRight, end: resultVoxel.bottomRight, visible: true });
|
||||
colors[0] = {red: intersection.voxel.red, green: intersection.voxel.green , blue: intersection.voxel.blue };
|
||||
|
||||
if (copyScale) {
|
||||
scaleSelector.setScale(intersection.voxel.s);
|
||||
scaleSelector.update();
|
||||
}
|
||||
moveTools();
|
||||
} else {
|
||||
Overlays.editOverlay(voxelPreview, { visible: false });
|
||||
Overlays.editOverlay(linePreviewTop, { visible: false });
|
||||
|
@ -756,7 +848,7 @@ function showPreviewLines() {
|
|||
}
|
||||
|
||||
function showPreviewGuides() {
|
||||
if (editToolsOn) {
|
||||
if (editToolsOn && !isImporting) {
|
||||
if (previewAsVoxel) {
|
||||
showPreviewVoxel();
|
||||
|
||||
|
@ -817,6 +909,7 @@ function trackKeyReleaseEvent(event) {
|
|||
moveTools();
|
||||
setAudioPosition(); // make sure we set the audio position before playing sounds
|
||||
showPreviewGuides();
|
||||
scaleSelector.show(editToolsOn);
|
||||
scriptInitSound.playRandom();
|
||||
}
|
||||
|
||||
|
@ -826,17 +919,14 @@ function trackKeyReleaseEvent(event) {
|
|||
|
||||
if (editToolsOn) {
|
||||
if (event.text == "ESC") {
|
||||
pointerVoxelScaleSet = false;
|
||||
pasteMode = false;
|
||||
moveTools();
|
||||
}
|
||||
if (event.text == "-") {
|
||||
thumbX -= thumbDeltaPerStep;
|
||||
calcScaleFromThumb(thumbX);
|
||||
scaleSelector.decrementScale();
|
||||
}
|
||||
if (event.text == "+") {
|
||||
thumbX += thumbDeltaPerStep;
|
||||
calcScaleFromThumb(thumbX);
|
||||
scaleSelector.incrementScale();
|
||||
}
|
||||
if (event.text == "CONTROL") {
|
||||
trackAsDelete = false;
|
||||
|
@ -872,15 +962,7 @@ function mousePressEvent(event) {
|
|||
var clickedOnSomething = false;
|
||||
var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y});
|
||||
|
||||
// If the user clicked on the thumb, handle the slider logic
|
||||
if (clickedOverlay == thumb) {
|
||||
isMovingSlider = true;
|
||||
thumbClickOffsetX = event.x - (sliderX + thumbX); // this should be the position of the mouse relative to the thumb
|
||||
clickedOnSomething = true;
|
||||
|
||||
Overlays.editOverlay(thumb, { imageURL: toolIconUrl + "voxel-size-slider-handle.svg", });
|
||||
|
||||
} else if (clickedOverlay == voxelTool) {
|
||||
if (clickedOverlay == voxelTool) {
|
||||
modeSwitchSound.play(0);
|
||||
voxelToolSelected = true;
|
||||
recolorToolSelected = false;
|
||||
|
@ -901,19 +983,10 @@ function mousePressEvent(event) {
|
|||
eyedropperToolSelected = true;
|
||||
moveTools();
|
||||
clickedOnSomething = true;
|
||||
} else if (clickedOverlay == slider) {
|
||||
|
||||
if (event.x < sliderX + minThumbX) {
|
||||
thumbX -= thumbDeltaPerStep;
|
||||
calcScaleFromThumb(thumbX);
|
||||
} else if (scaleSelector.clicked(event.x, event.y)) {
|
||||
if (isImporting) {
|
||||
rescaleImport();
|
||||
}
|
||||
|
||||
if (event.x > sliderX + maxThumbX) {
|
||||
thumbX += thumbDeltaPerStep;
|
||||
calcScaleFromThumb(thumbX);
|
||||
}
|
||||
|
||||
moveTools();
|
||||
clickedOnSomething = true;
|
||||
} else {
|
||||
// if the user clicked on one of the color swatches, update the selectedSwatch
|
||||
|
@ -927,7 +1000,7 @@ function mousePressEvent(event) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (clickedOnSomething) {
|
||||
if (clickedOnSomething || isImporting) {
|
||||
return; // no further processing
|
||||
}
|
||||
|
||||
|
@ -939,14 +1012,6 @@ function mousePressEvent(event) {
|
|||
var intersection = Voxels.findRayIntersection(pickRay);
|
||||
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);
|
||||
|
@ -956,11 +1021,6 @@ function mousePressEvent(event) {
|
|||
}
|
||||
|
||||
if (intersection.intersects) {
|
||||
// if the user hasn't updated the
|
||||
if (!pointerVoxelScaleSet) {
|
||||
calcThumbFromScale(intersection.voxel.s);
|
||||
}
|
||||
|
||||
if (trackAsDelete || event.isRightButton && !trackAsEyedropper) {
|
||||
// Delete voxel
|
||||
voxelDetails = calculateVoxelFromIntersection(intersection,"delete");
|
||||
|
@ -968,13 +1028,11 @@ function mousePressEvent(event) {
|
|||
delVoxelSound.playRandom();
|
||||
Overlays.editOverlay(voxelPreview, { visible: false });
|
||||
} else if (eyedropperToolSelected || trackAsEyedropper) {
|
||||
if (whichColor != -1) {
|
||||
colors[whichColor].red = intersection.voxel.red;
|
||||
colors[whichColor].green = intersection.voxel.green;
|
||||
colors[whichColor].blue = intersection.voxel.blue;
|
||||
moveTools();
|
||||
swatchesSound.play(whichColor);
|
||||
}
|
||||
|
||||
} else if (recolorToolSelected || trackAsRecolor) {
|
||||
// Recolor Voxel
|
||||
|
@ -987,18 +1045,10 @@ function mousePressEvent(event) {
|
|||
Overlays.editOverlay(voxelPreview, { visible: false });
|
||||
} else if (voxelToolSelected) {
|
||||
// Add voxel on face
|
||||
if (whichColor == -1) {
|
||||
// Copy mode - use clicked voxel color
|
||||
newColor = {
|
||||
red: intersection.voxel.red,
|
||||
green: intersection.voxel.green,
|
||||
blue: intersection.voxel.blue };
|
||||
} else {
|
||||
newColor = {
|
||||
red: colors[whichColor].red,
|
||||
newColor = { red: colors[whichColor].red,
|
||||
green: colors[whichColor].green,
|
||||
blue: colors[whichColor].blue };
|
||||
}
|
||||
blue: colors[whichColor].blue
|
||||
};
|
||||
|
||||
voxelDetails = calculateVoxelFromIntersection(intersection,"add");
|
||||
Voxels.setVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s,
|
||||
|
@ -1021,10 +1071,7 @@ function keyPressEvent(event) {
|
|||
if (editToolsOn) {
|
||||
var nVal = parseInt(event.text);
|
||||
if (event.text == "`") {
|
||||
print("Color = Copy");
|
||||
whichColor = -1;
|
||||
colorInheritSound.playRandom();
|
||||
moveTools();
|
||||
copyScale = true;
|
||||
} else if ((nVal > 0) && (nVal <= numColors)) {
|
||||
whichColor = nVal - 1;
|
||||
print("Color = " + (whichColor + 1));
|
||||
|
@ -1032,17 +1079,15 @@ function keyPressEvent(event) {
|
|||
moveTools();
|
||||
} else if (event.text == "0") {
|
||||
// Create a brand new 1 meter voxel in front of your avatar
|
||||
var color = whichColor;
|
||||
if (color == -1) color = 0;
|
||||
var newPosition = getNewVoxelPosition();
|
||||
var newVoxel = {
|
||||
x: newPosition.x,
|
||||
y: newPosition.y ,
|
||||
z: newPosition.z,
|
||||
s: NEW_VOXEL_SIZE,
|
||||
red: colors[color].red,
|
||||
green: colors[color].green,
|
||||
blue: colors[color].blue };
|
||||
red: colors[whichColor].red,
|
||||
green: colors[whichColor].green,
|
||||
blue: colors[whichColor].blue };
|
||||
Voxels.eraseVoxel(newVoxel.x, newVoxel.y, newVoxel.z, newVoxel.s);
|
||||
Voxels.setVoxel(newVoxel.x, newVoxel.y, newVoxel.z, newVoxel.s, newVoxel.red, newVoxel.green, newVoxel.blue);
|
||||
setAudioPosition();
|
||||
|
@ -1158,17 +1203,44 @@ function mouseMoveEvent(event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (isMovingSlider) {
|
||||
thumbX = (event.x - thumbClickOffsetX) - sliderX;
|
||||
if (thumbX < minThumbX) {
|
||||
thumbX = minThumbX;
|
||||
}
|
||||
if (thumbX > maxThumbX) {
|
||||
thumbX = maxThumbX;
|
||||
}
|
||||
calcScaleFromThumb(thumbX);
|
||||
// Move Import Preview
|
||||
if (isImporting) {
|
||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||
var intersection = Voxels.findRayIntersection(pickRay);
|
||||
|
||||
} else if (isAdding) {
|
||||
var distance = 2 * scaleSelector.scale;
|
||||
|
||||
if (intersection.intersects) {
|
||||
var intersectionDistance = Vec3.length(Vec3.subtract(pickRay.origin, intersection.intersection));
|
||||
if (intersectionDistance < distance) {
|
||||
distance = intersectionDistance * 0.99;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var targetPosition = { x: pickRay.direction.x * distance,
|
||||
y: pickRay.direction.y * distance,
|
||||
z: pickRay.direction.z * distance
|
||||
};
|
||||
targetPosition.x += pickRay.origin.x;
|
||||
targetPosition.y += pickRay.origin.y;
|
||||
targetPosition.z += pickRay.origin.z;
|
||||
|
||||
if (targetPosition.x < 0) targetPosition.x = 0;
|
||||
if (targetPosition.y < 0) targetPosition.y = 0;
|
||||
if (targetPosition.z < 0) targetPosition.z = 0;
|
||||
|
||||
var nudgeFactor = scaleSelector.scale;
|
||||
var newPosition = {
|
||||
x: Math.floor(targetPosition.x / nudgeFactor) * nudgeFactor,
|
||||
y: Math.floor(targetPosition.y / nudgeFactor) * nudgeFactor,
|
||||
z: Math.floor(targetPosition.z / nudgeFactor) * nudgeFactor
|
||||
}
|
||||
|
||||
moveImport(newPosition);
|
||||
}
|
||||
|
||||
if (isAdding) {
|
||||
// Watch the drag direction to tell which way to 'extrude' this voxel
|
||||
if (!isExtruding) {
|
||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||
|
@ -1220,16 +1292,13 @@ function mouseReleaseEvent(event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (isMovingSlider) {
|
||||
isMovingSlider = false;
|
||||
}
|
||||
isAdding = false;
|
||||
isExtruding = false;
|
||||
}
|
||||
|
||||
function moveTools() {
|
||||
// move the swatches
|
||||
swatchesX = (windowDimensions.x - (swatchesWidth + sliderWidth)) / 2;
|
||||
swatchesX = (windowDimensions.x - (swatchesWidth + scaleSelectorWidth)) / 2;
|
||||
swatchesY = windowDimensions.y - swatchHeight + 1;
|
||||
|
||||
// create the overlays, position them in a row, set their colors, and for the selected one, use a different source image
|
||||
|
@ -1302,14 +1371,7 @@ function moveTools() {
|
|||
visible: editToolsOn
|
||||
});
|
||||
|
||||
sliderX = swatchesX + swatchesWidth - sliderOffsetX;
|
||||
sliderY = windowDimensions.y - sliderHeight + 1;
|
||||
thumbY = sliderY + thumbOffsetY;
|
||||
Overlays.editOverlay(slider, { x: sliderX, y: sliderY, visible: editToolsOn });
|
||||
|
||||
// This is the thumb of our slider
|
||||
Overlays.editOverlay(thumb, { x: sliderX + thumbX, y: thumbY, visible: editToolsOn });
|
||||
|
||||
scaleSelector.move();
|
||||
}
|
||||
|
||||
var lastFingerAddVoxel = { x: -1, y: -1, z: -1}; // off of the build-able area
|
||||
|
@ -1330,11 +1392,7 @@ function checkControllers() {
|
|||
|
||||
if (Controller.isButtonPressed(BUTTON_1)) {
|
||||
if (Vec3.length(Vec3.subtract(fingerTipPosition,lastFingerAddVoxel)) > (FINGERTIP_VOXEL_SIZE / 2)) {
|
||||
if (whichColor == -1) {
|
||||
newColor = { red: colors[0].red, green: colors[0].green, blue: colors[0].blue };
|
||||
} else {
|
||||
newColor = { red: colors[whichColor].red, green: colors[whichColor].green, blue: colors[whichColor].blue };
|
||||
}
|
||||
|
||||
Voxels.eraseVoxel(fingerTipPosition.x, fingerTipPosition.y, fingerTipPosition.z, FINGERTIP_VOXEL_SIZE);
|
||||
Voxels.setVoxel(fingerTipPosition.x, fingerTipPosition.y, fingerTipPosition.z, FINGERTIP_VOXEL_SIZE,
|
||||
|
@ -1360,19 +1418,6 @@ function update(deltaTime) {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1380,28 +1425,17 @@ function wheelEvent(event) {
|
|||
wheelPixelsMoved += event.delta;
|
||||
if (Math.abs(wheelPixelsMoved) > WHEEL_PIXELS_PER_SCALE_CHANGE)
|
||||
{
|
||||
if (!pointerVoxelScaleSet) {
|
||||
pointerVoxelScale = 1.0;
|
||||
pointerVoxelScaleSet = true;
|
||||
}
|
||||
|
||||
if (wheelPixelsMoved > 0) {
|
||||
pointerVoxelScale /= 2.0;
|
||||
if (pointerVoxelScale < MIN_VOXEL_SCALE) {
|
||||
pointerVoxelScale = MIN_VOXEL_SCALE;
|
||||
}
|
||||
scaleSelector.decrementScale();
|
||||
} else {
|
||||
pointerVoxelScale *= 2.0;
|
||||
if (pointerVoxelScale > MAX_VOXEL_SCALE) {
|
||||
pointerVoxelScale = MAX_VOXEL_SCALE;
|
||||
scaleSelector.incrementScale();
|
||||
}
|
||||
}
|
||||
calcThumbFromScale(pointerVoxelScale);
|
||||
trackMouseEvent(event);
|
||||
wheelPixelsMoved = 0;
|
||||
|
||||
if (isImporting) {
|
||||
var importScale = (pointerVoxelScale / MAX_VOXEL_SCALE) * MAX_PASTE_VOXEL_SCALE;
|
||||
rescaleImport(importScale);
|
||||
rescaleImport();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1428,11 +1462,10 @@ function scriptEnding() {
|
|||
Overlays.deleteOverlay(voxelTool);
|
||||
Overlays.deleteOverlay(recolorTool);
|
||||
Overlays.deleteOverlay(eyedropperTool);
|
||||
Overlays.deleteOverlay(slider);
|
||||
Overlays.deleteOverlay(thumb);
|
||||
Controller.releaseKeyEvents({ text: "+" });
|
||||
Controller.releaseKeyEvents({ text: "-" });
|
||||
cleanupImport();
|
||||
scaleSelector.cleanup();
|
||||
cleanupMenus();
|
||||
}
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
|
|
@ -356,6 +356,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
QMutexLocker locker(&_settingsMutex);
|
||||
_previousScriptLocation = _settings->value("LastScriptLocation", QVariant("")).toString();
|
||||
}
|
||||
//When -url in command line, teleport to location
|
||||
urlGoTo(argc, constArgv);
|
||||
}
|
||||
|
||||
Application::~Application() {
|
||||
|
@ -820,6 +822,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
break;
|
||||
|
||||
case Qt::Key_E:
|
||||
case Qt::Key_PageUp:
|
||||
if (!_myAvatar->getDriveKeys(UP)) {
|
||||
_myAvatar->jump();
|
||||
}
|
||||
|
@ -831,6 +834,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
break;
|
||||
|
||||
case Qt::Key_C:
|
||||
case Qt::Key_PageDown:
|
||||
_myAvatar->setDriveKeys(DOWN, 1.f);
|
||||
break;
|
||||
|
||||
|
@ -1017,10 +1021,12 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
|||
|
||||
switch (event->key()) {
|
||||
case Qt::Key_E:
|
||||
case Qt::Key_PageUp:
|
||||
_myAvatar->setDriveKeys(UP, 0.f);
|
||||
break;
|
||||
|
||||
case Qt::Key_C:
|
||||
case Qt::Key_PageDown:
|
||||
_myAvatar->setDriveKeys(DOWN, 0.f);
|
||||
break;
|
||||
|
||||
|
@ -2732,7 +2738,7 @@ void Application::displayOverlay() {
|
|||
(Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth))
|
||||
? 80 : 20;
|
||||
drawText(_glWidget->width() - 100, _glWidget->height() - timerBottom, 0.30f, 1.0f, 0.f, frameTimer, WHITE_TEXT);
|
||||
drawText(_glWidget->width() - 100, _glWidget->height() - timerBottom, 0.30f, 0.0f, 0, frameTimer, WHITE_TEXT);
|
||||
}
|
||||
|
||||
_overlays.render2D();
|
||||
|
@ -3566,3 +3572,38 @@ void Application::takeSnapshot() {
|
|||
|
||||
Snapshot::saveSnapshot(_glWidget, _myAvatar);
|
||||
}
|
||||
|
||||
void Application::urlGoTo(int argc, const char * constArgv[]) {
|
||||
//Gets the url (hifi://domain/destination/orientation)
|
||||
QString customUrl = getCmdOption(argc, constArgv, "-url");
|
||||
|
||||
if (customUrl.startsWith("hifi://")) {
|
||||
QStringList urlParts = customUrl.remove(0, CUSTOM_URL_SCHEME.length() + 2).split('/', QString::SkipEmptyParts);
|
||||
if (urlParts.count() > 1) {
|
||||
// if url has 2 or more parts, the first one is domain name
|
||||
QString domain = urlParts[0];
|
||||
|
||||
// second part is either a destination coordinate or
|
||||
// a place name
|
||||
QString destination = urlParts[1];
|
||||
|
||||
// any third part is an avatar orientation.
|
||||
QString orientation = urlParts.count() > 2 ? urlParts[2] : QString();
|
||||
|
||||
Menu::goToDomain(domain);
|
||||
|
||||
// goto either @user, #place, or x-xx,y-yy,z-zz
|
||||
// style co-ordinate.
|
||||
Menu::goTo(destination);
|
||||
|
||||
if (!orientation.isEmpty()) {
|
||||
// location orientation
|
||||
Menu::goToOrientation(orientation);
|
||||
}
|
||||
} else if (urlParts.count() == 1) {
|
||||
// location coordinates or place name
|
||||
QString destination = urlParts[0];
|
||||
Menu::goTo(destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,6 +129,7 @@ public:
|
|||
void initializeGL();
|
||||
void paintGL();
|
||||
void resizeGL(int width, int height);
|
||||
void urlGoTo(int argc, const char * constArgv[]);
|
||||
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void keyReleaseEvent(QKeyEvent* event);
|
||||
|
|
|
@ -1068,7 +1068,6 @@ bool Audio::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo)
|
|||
|
||||
delete _audioOutput;
|
||||
_audioOutput = NULL;
|
||||
_numInputCallbackBytes = 0;
|
||||
|
||||
_loopbackOutputDevice = NULL;
|
||||
delete _loopbackAudioOutput;
|
||||
|
|
|
@ -316,6 +316,7 @@ Menu::Menu() :
|
|||
appInstance->getVisage(), SLOT(updateEnabled()));
|
||||
#endif
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::GlowWhenSpeaking, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false);
|
||||
|
||||
QMenu* handOptionsMenu = developerMenu->addMenu("Hand Options");
|
||||
|
|
|
@ -135,10 +135,10 @@ public:
|
|||
|
||||
void removeAction(QMenu* menu, const QString& actionName);
|
||||
|
||||
bool goToDestination(QString destination);
|
||||
void goToOrientation(QString orientation);
|
||||
void goToDomain(const QString newDomain);
|
||||
void goTo(QString destination);
|
||||
bool static goToDestination(QString destination);
|
||||
void static goToOrientation(QString orientation);
|
||||
void static goToDomain(const QString newDomain);
|
||||
void static goTo(QString destination);
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -304,6 +304,7 @@ namespace MenuOption {
|
|||
const QString Fullscreen = "Fullscreen";
|
||||
const QString FullscreenMirror = "Fullscreen Mirror";
|
||||
const QString GlowMode = "Cycle Glow Mode";
|
||||
const QString GlowWhenSpeaking = "Glow When Speaking";
|
||||
const QString GoHome = "Go Home";
|
||||
const QString GoTo = "Go To...";
|
||||
const QString GoToDomain = "Go To Domain...";
|
||||
|
|
|
@ -34,6 +34,7 @@ static const QString TEXDIR_FIELD = "texdir";
|
|||
static const QString LOD_FIELD = "lod";
|
||||
|
||||
static const QString S3_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com";
|
||||
static const QString DATA_SERVER_URL = "https://data-web.highfidelity.io";
|
||||
static const QString MODEL_URL = "/api/v1/models";
|
||||
|
||||
static const QString SETTING_NAME = "LastModelUploadLocation";
|
||||
|
@ -201,14 +202,14 @@ void ModelUploader::send() {
|
|||
|
||||
JSONCallbackParameters callbackParams;
|
||||
callbackParams.jsonCallbackReceiver = this;
|
||||
callbackParams.jsonCallbackMethod = "uploadSuccess";
|
||||
callbackParams.jsonCallbackMethod = "checkJSON";
|
||||
callbackParams.errorCallbackReceiver = this;
|
||||
callbackParams.errorCallbackMethod = "uploadFailed";
|
||||
callbackParams.updateReciever = this;
|
||||
callbackParams.updateSlot = SLOT(uploadUpdate(qint64, qint64));
|
||||
|
||||
AccountManager::getInstance().authenticatedRequest(MODEL_URL, QNetworkAccessManager::PostOperation, callbackParams, QByteArray(), _dataMultiPart);
|
||||
_dataMultiPart = NULL;
|
||||
AccountManager::getInstance().authenticatedRequest(MODEL_URL + "/" + QFileInfo(_url).baseName(),
|
||||
QNetworkAccessManager::GetOperation,
|
||||
callbackParams);
|
||||
|
||||
qDebug() << "Sending model...";
|
||||
_progressDialog = new QDialog();
|
||||
_progressBar = new QProgressBar(_progressDialog);
|
||||
|
@ -226,6 +227,61 @@ void ModelUploader::send() {
|
|||
_progressBar = NULL;
|
||||
}
|
||||
|
||||
void ModelUploader::checkJSON(const QJsonObject& jsonResponse) {
|
||||
if (jsonResponse.contains("status") && jsonResponse.value("status").toString() == "success") {
|
||||
qDebug() << "status : success";
|
||||
JSONCallbackParameters callbackParams;
|
||||
callbackParams.jsonCallbackReceiver = this;
|
||||
callbackParams.jsonCallbackMethod = "uploadSuccess";
|
||||
callbackParams.errorCallbackReceiver = this;
|
||||
callbackParams.errorCallbackMethod = "uploadFailed";
|
||||
callbackParams.updateReciever = this;
|
||||
callbackParams.updateSlot = SLOT(uploadUpdate(qint64, qint64));
|
||||
|
||||
if (jsonResponse.contains("exists") && jsonResponse.value("exists").toBool()) {
|
||||
qDebug() << "exists : true";
|
||||
if (jsonResponse.contains("can_update") && jsonResponse.value("can_update").toBool()) {
|
||||
qDebug() << "can_update : true";
|
||||
|
||||
AccountManager::getInstance().authenticatedRequest(MODEL_URL + "/" + QFileInfo(_url).baseName(),
|
||||
QNetworkAccessManager::PutOperation,
|
||||
callbackParams,
|
||||
QByteArray(),
|
||||
_dataMultiPart);
|
||||
_dataMultiPart = NULL;
|
||||
} else {
|
||||
qDebug() << "can_update : false";
|
||||
if (_progressDialog) {
|
||||
_progressDialog->reject();
|
||||
}
|
||||
QMessageBox::warning(NULL,
|
||||
QString("ModelUploader::checkJSON()"),
|
||||
QString("This model already exist and is own by someone else."),
|
||||
QMessageBox::Ok);
|
||||
deleteLater();
|
||||
}
|
||||
} else {
|
||||
qDebug() << "exists : false";
|
||||
AccountManager::getInstance().authenticatedRequest(MODEL_URL,
|
||||
QNetworkAccessManager::PostOperation,
|
||||
callbackParams,
|
||||
QByteArray(),
|
||||
_dataMultiPart);
|
||||
_dataMultiPart = NULL;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "status : failed";
|
||||
if (_progressDialog) {
|
||||
_progressDialog->reject();
|
||||
}
|
||||
QMessageBox::warning(NULL,
|
||||
QString("ModelUploader::checkJSON()"),
|
||||
QString("Something went wrong with the data-server."),
|
||||
QMessageBox::Ok);
|
||||
deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void ModelUploader::uploadUpdate(qint64 bytesSent, qint64 bytesTotal) {
|
||||
if (_progressDialog) {
|
||||
_progressBar->setRange(0, bytesTotal);
|
||||
|
@ -249,11 +305,11 @@ void ModelUploader::uploadFailed(QNetworkReply::NetworkError errorCode, const QS
|
|||
if (_progressDialog) {
|
||||
_progressDialog->reject();
|
||||
}
|
||||
qDebug() << "Model upload failed (" << errorCode << "): " << errorString;
|
||||
QMessageBox::warning(NULL,
|
||||
QString("ModelUploader::uploadFailed()"),
|
||||
QString("There was a problem with your upload, please try again later."),
|
||||
QMessageBox::Ok);
|
||||
qDebug() << "Model upload failed (" << errorCode << "): " << errorString;
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ public slots:
|
|||
void send();
|
||||
|
||||
private slots:
|
||||
void checkJSON(const QJsonObject& jsonResponse);
|
||||
void uploadUpdate(qint64 bytesSent, qint64 bytesTotal);
|
||||
void uploadSuccess(const QJsonObject& jsonResponse);
|
||||
void uploadFailed(QNetworkReply::NetworkError errorCode, const QString& errorString);
|
||||
|
|
|
@ -211,9 +211,14 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
|
|||
const float GLOW_DISTANCE = 20.0f;
|
||||
const float GLOW_MAX_LOUDNESS = 2500.0f;
|
||||
const float MAX_GLOW = 0.5f;
|
||||
const float GLOW_FROM_AVERAGE_LOUDNESS = ((this == Application::getInstance()->getAvatar())
|
||||
|
||||
float GLOW_FROM_AVERAGE_LOUDNESS = ((this == Application::getInstance()->getAvatar())
|
||||
? 0.0f
|
||||
: MAX_GLOW * getHeadData()->getAudioLoudness() / GLOW_MAX_LOUDNESS);
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::GlowWhenSpeaking)) {
|
||||
GLOW_FROM_AVERAGE_LOUDNESS = 0.0f;
|
||||
}
|
||||
|
||||
Glower glower(_moving && distanceToTarget > GLOW_DISTANCE && renderMode == NORMAL_RENDER_MODE
|
||||
? 1.0f
|
||||
: GLOW_FROM_AVERAGE_LOUDNESS);
|
||||
|
|
|
@ -468,6 +468,11 @@ void Model::clearShapes() {
|
|||
|
||||
void Model::rebuildShapes() {
|
||||
clearShapes();
|
||||
|
||||
if (!_geometry) {
|
||||
return;
|
||||
}
|
||||
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
|
||||
if (geometry.joints.isEmpty()) {
|
||||
|
|
|
@ -78,7 +78,7 @@ void ClipboardScriptingInterface::exportVoxel(float x, float y, float z, float s
|
|||
}
|
||||
|
||||
bool ClipboardScriptingInterface::importVoxels() {
|
||||
qDebug() << "[DEBUG] Importing ... ";
|
||||
qDebug() << "Importing ... ";
|
||||
QEventLoop loop;
|
||||
connect(Application::getInstance(), SIGNAL(importDone()), &loop, SLOT(quit()));
|
||||
emit readyToImport();
|
||||
|
|
|
@ -171,6 +171,9 @@ void Stats::display(
|
|||
|
||||
unsigned int backgroundColor = 0x33333399;
|
||||
int verticalOffset = 0, lines = 0;
|
||||
float scale = 0.10f;
|
||||
float rotation = 0.0f;
|
||||
int font = 2;
|
||||
|
||||
QLocale locale(QLocale::English);
|
||||
std::stringstream voxelStats;
|
||||
|
@ -198,11 +201,11 @@ void Stats::display(
|
|||
sprintf(framesPerSecond, "Framerate: %3.0f FPS", fps);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, serverNodes, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, serverNodes, color);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarNodes, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, avatarNodes, color);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, framesPerSecond, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, framesPerSecond, color);
|
||||
|
||||
if (_expanded) {
|
||||
char packetsPerSecondString[30];
|
||||
|
@ -211,9 +214,9 @@ void Stats::display(
|
|||
sprintf(averageMegabitsPerSecond, "Mbps: %3.2f", (float)bytesPerSecond * 8.f / 1000000.f);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, packetsPerSecondString, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, packetsPerSecondString, color);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, averageMegabitsPerSecond, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, averageMegabitsPerSecond, color);
|
||||
}
|
||||
|
||||
verticalOffset = 0;
|
||||
|
@ -258,7 +261,7 @@ void Stats::display(
|
|||
"Buffer msecs %.1f",
|
||||
(float) (audio->getNetworkBufferLengthSamplesPerChannel() + (float) audio->getJitterBufferSamples()) /
|
||||
(float) audio->getNetworkSampleRate() * 1000.f);
|
||||
drawText(30, glWidget->height() - 22, 0.10f, 0.f, 2.f, audioJitter, color);
|
||||
drawText(30, glWidget->height() - 22, scale, rotation, font, audioJitter, color);
|
||||
|
||||
|
||||
char audioPing[30];
|
||||
|
@ -271,18 +274,18 @@ void Stats::display(
|
|||
sprintf(voxelAvgPing, "Voxel avg ping: %d", pingVoxel);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, audioPing, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, audioPing, color);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarPing, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, avatarPing, color);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, voxelAvgPing, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, voxelAvgPing, color);
|
||||
|
||||
if (_expanded) {
|
||||
char voxelMaxPing[30];
|
||||
sprintf(voxelMaxPing, "Voxel max ping: %d", pingVoxelMax);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, voxelMaxPing, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, voxelMaxPing, color);
|
||||
}
|
||||
|
||||
verticalOffset = 0;
|
||||
|
@ -306,11 +309,11 @@ void Stats::display(
|
|||
char avatarMixerStats[200];
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarPosition, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, avatarPosition, color);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarVelocity, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, avatarVelocity, color);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarBodyYaw, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, avatarBodyYaw, color);
|
||||
|
||||
if (_expanded) {
|
||||
SharedNodePointer avatarMixer = NodeList::getInstance()->soloNodeOfType(NodeType::AvatarMixer);
|
||||
|
@ -323,7 +326,7 @@ void Stats::display(
|
|||
}
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarMixerStats, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, avatarMixerStats, color);
|
||||
|
||||
stringstream downloads;
|
||||
downloads << "Downloads: ";
|
||||
|
@ -333,7 +336,7 @@ void Stats::display(
|
|||
downloads << "(" << ResourceCache::getPendingRequestCount() << " pending)";
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, downloads.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, downloads.str().c_str(), color);
|
||||
}
|
||||
|
||||
verticalOffset = 0;
|
||||
|
@ -354,7 +357,7 @@ void Stats::display(
|
|||
voxelStats.str("");
|
||||
voxelStats << "Voxels Memory Nodes: " << VoxelTreeElement::getTotalMemoryUsage() / 1000000.f << "MB";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
|
||||
voxelStats.str("");
|
||||
voxelStats <<
|
||||
|
@ -364,14 +367,14 @@ void Stats::display(
|
|||
voxelStats << " / GPU: " << voxels->getVoxelMemoryUsageGPU() / 1000000.f << "MB";
|
||||
}
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
|
||||
// Voxel Rendering
|
||||
voxelStats.str("");
|
||||
voxelStats.precision(4);
|
||||
voxelStats << "Voxel Rendering Slots Max: " << voxels->getMaxVoxels() / 1000.f << "K";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
}
|
||||
|
||||
voxelStats.str("");
|
||||
|
@ -379,7 +382,7 @@ void Stats::display(
|
|||
voxelStats << "Drawn: " << voxels->getVoxelsWritten() / 1000.f << "K " <<
|
||||
"Abandoned: " << voxels->getAbandonedVoxels() / 1000.f << "K ";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
|
||||
// iterate all the current voxel stats, and list their sending modes, and total voxel counts
|
||||
std::stringstream sendingMode("");
|
||||
|
@ -424,7 +427,7 @@ void Stats::display(
|
|||
sendingMode << " <SCENE STABLE>";
|
||||
}
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)sendingMode.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)sendingMode.str().c_str(), color);
|
||||
}
|
||||
|
||||
// Incoming packets
|
||||
|
@ -435,7 +438,7 @@ void Stats::display(
|
|||
voxelStats << "Voxel Packets to Process: " << qPrintable(packetsString)
|
||||
<< " [Recent Max: " << qPrintable(maxString) << "]";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
}
|
||||
|
||||
if (_resetRecentMaxPacketsSoon && voxelPacketsToProcess > 0) {
|
||||
|
@ -458,7 +461,7 @@ void Stats::display(
|
|||
voxelStats.str("");
|
||||
voxelStats << "Server voxels: " << qPrintable(serversTotalString);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
|
||||
if (_expanded) {
|
||||
QString serversInternalString = locale.toString((uint)totalInternal);
|
||||
|
@ -469,7 +472,7 @@ void Stats::display(
|
|||
"Internal: " << qPrintable(serversInternalString) << " " <<
|
||||
"Leaves: " << qPrintable(serversLeavesString) << "";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
}
|
||||
|
||||
unsigned long localTotal = VoxelTreeElement::getNodeCount();
|
||||
|
@ -479,7 +482,7 @@ void Stats::display(
|
|||
voxelStats.str("");
|
||||
voxelStats << "Local voxels: " << qPrintable(localTotalString);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
|
||||
if (_expanded) {
|
||||
unsigned long localInternal = VoxelTreeElement::getInternalNodeCount();
|
||||
|
@ -492,7 +495,7 @@ void Stats::display(
|
|||
"Internal: " << qPrintable(localInternalString) << " " <<
|
||||
"Leaves: " << qPrintable(localLeavesString) << "";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
}
|
||||
|
||||
// LOD Details
|
||||
|
@ -501,7 +504,7 @@ void Stats::display(
|
|||
QString displayLODDetails = Menu::getInstance()->getLODFeedbackText();
|
||||
voxelStats << "LOD: You can see " << qPrintable(displayLODDetails.trimmed());
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, (char*)voxelStats.str().c_str(), color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
}
|
||||
|
||||
|
||||
|
@ -526,7 +529,7 @@ void Stats::display(
|
|||
);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, reflectionsStatus, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, reflectionsStatus, color);
|
||||
|
||||
float preDelay = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingPreDelay) ?
|
||||
audioReflector->getPreDelay() : 0.0f;
|
||||
|
@ -539,7 +542,8 @@ void Stats::display(
|
|||
audioReflector->getSoundMsPerMeter());
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, reflectionsStatus, color);
|
||||
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, reflectionsStatus, color);
|
||||
|
||||
bool distanceAttenuationDisabled = Menu::getInstance()->isOptionChecked(
|
||||
MenuOption::AudioSpatialProcessingDontDistanceAttenuate);
|
||||
|
@ -556,7 +560,7 @@ void Stats::display(
|
|||
audioReflector->getDistanceAttenuationScalingFactor());
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, reflectionsStatus, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, reflectionsStatus, color);
|
||||
|
||||
sprintf(reflectionsStatus, "Local Audio: %s Attenuation: %5.3f",
|
||||
(Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingProcessLocalAudio)
|
||||
|
@ -564,7 +568,7 @@ void Stats::display(
|
|||
audioReflector->getLocalAudioAttenuationFactor());
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, reflectionsStatus, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, reflectionsStatus, color);
|
||||
|
||||
bool diffusionEnabled = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingWithDiffusions);
|
||||
int fanout = diffusionEnabled ? audioReflector->getDiffusionFanout() : 0;
|
||||
|
@ -573,7 +577,7 @@ void Stats::display(
|
|||
(diffusionEnabled ? "yes" : "no"), fanout, diffusionPaths);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, reflectionsStatus, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, reflectionsStatus, color);
|
||||
|
||||
const float AS_PERCENT = 100.0f;
|
||||
float reflectiveRatio = audioReflector->getReflectiveRatio() * AS_PERCENT;
|
||||
|
@ -583,7 +587,7 @@ void Stats::display(
|
|||
reflectiveRatio, diffusionRatio, absorptionRatio);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, reflectionsStatus, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, reflectionsStatus, color);
|
||||
|
||||
sprintf(reflectionsStatus, "Comb Filter Window: %5.3f ms, Allowed: %d, Suppressed: %d",
|
||||
audioReflector->getCombFilterWindow(),
|
||||
|
@ -591,7 +595,7 @@ void Stats::display(
|
|||
audioReflector->getEchoesSuppressed());
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, reflectionsStatus, color);
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, reflectionsStatus, color);
|
||||
|
||||
sprintf(reflectionsStatus, "Wet/Dry Mix: Original: %5.3f Echoes: %5.3f",
|
||||
audioReflector->getOriginalSourceAttenuation(),
|
||||
|
|
|
@ -40,6 +40,7 @@ void Cube3DOverlay::render() {
|
|||
if (_isSolid) {
|
||||
glutSolidCube(_size);
|
||||
} else {
|
||||
glLineWidth(_lineWidth);
|
||||
glutWireCube(_size);
|
||||
}
|
||||
glPopMatrix();
|
||||
|
|
|
@ -67,7 +67,8 @@ Sound::Sound(float volume, float frequency, float duration, float decay, QObject
|
|||
}
|
||||
|
||||
Sound::Sound(const QUrl& sampleURL, QObject* parent) :
|
||||
QObject(parent)
|
||||
QObject(parent),
|
||||
_hasDownloaded(false)
|
||||
{
|
||||
// assume we have a QApplication or QCoreApplication instance and use the
|
||||
// QNetworkAccess manager to grab the raw audio file at the given URL
|
||||
|
@ -111,6 +112,8 @@ void Sound::replyFinished() {
|
|||
} else {
|
||||
qDebug() << "Network reply without 'Content-Type'.";
|
||||
}
|
||||
|
||||
_hasDownloaded = true;
|
||||
}
|
||||
|
||||
void Sound::replyError(QNetworkReply::NetworkError code) {
|
||||
|
|
|
@ -18,17 +18,18 @@
|
|||
class Sound : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(bool empty READ isEmpty)
|
||||
Q_PROPERTY(bool downloaded READ hasDownloaded)
|
||||
public:
|
||||
Sound(const QUrl& sampleURL, QObject* parent = NULL);
|
||||
Sound(float volume, float frequency, float duration, float decay, QObject* parent = NULL);
|
||||
|
||||
bool isEmpty() const { return _byteArray.isEmpty(); }
|
||||
bool hasDownloaded() const { return _hasDownloaded; }
|
||||
|
||||
const QByteArray& getByteArray() { return _byteArray; }
|
||||
|
||||
private:
|
||||
QByteArray _byteArray;
|
||||
bool _hasDownloaded;
|
||||
|
||||
void downSample(const QByteArray& rawAudioByteArray);
|
||||
void interpretAsWav(const QByteArray& inputAudioByteArray, QByteArray& outputAudioByteArray);
|
||||
|
|
|
@ -37,6 +37,9 @@ public:
|
|||
|
||||
public slots:
|
||||
|
||||
/// provide the world scale
|
||||
const int getTreeScale() const { return TREE_SCALE; }
|
||||
|
||||
/// checks the local voxel tree for a voxel at the specified location and scale
|
||||
/// \param x the x-coordinate of the voxel (in meter units)
|
||||
/// \param y the y-coordinate of the voxel (in meter units)
|
||||
|
|
Loading…
Reference in a new issue