mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 15:29:32 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into domain-tunnel
This commit is contained in:
commit
15156519b3
28 changed files with 443 additions and 237 deletions
|
@ -62,6 +62,7 @@
|
||||||
#include "AudioMixer.h"
|
#include "AudioMixer.h"
|
||||||
|
|
||||||
const float LOUDNESS_TO_DISTANCE_RATIO = 0.00001f;
|
const float LOUDNESS_TO_DISTANCE_RATIO = 0.00001f;
|
||||||
|
const float DEFAULT_ATTENUATION_PER_DOUBLING_IN_DISTANCE = 0.18;
|
||||||
|
|
||||||
const QString AUDIO_MIXER_LOGGING_TARGET_NAME = "audio-mixer";
|
const QString AUDIO_MIXER_LOGGING_TARGET_NAME = "audio-mixer";
|
||||||
|
|
||||||
|
@ -82,6 +83,7 @@ AudioMixer::AudioMixer(const QByteArray& packet) :
|
||||||
_trailingSleepRatio(1.0f),
|
_trailingSleepRatio(1.0f),
|
||||||
_minAudibilityThreshold(LOUDNESS_TO_DISTANCE_RATIO / 2.0f),
|
_minAudibilityThreshold(LOUDNESS_TO_DISTANCE_RATIO / 2.0f),
|
||||||
_performanceThrottlingRatio(0.0f),
|
_performanceThrottlingRatio(0.0f),
|
||||||
|
_attenuationPerDoublingInDistance(DEFAULT_ATTENUATION_PER_DOUBLING_IN_DISTANCE),
|
||||||
_numStatFrames(0),
|
_numStatFrames(0),
|
||||||
_sumListeners(0),
|
_sumListeners(0),
|
||||||
_sumMixes(0),
|
_sumMixes(0),
|
||||||
|
@ -104,7 +106,6 @@ AudioMixer::~AudioMixer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const float ATTENUATION_BEGINS_AT_DISTANCE = 1.0f;
|
const float ATTENUATION_BEGINS_AT_DISTANCE = 1.0f;
|
||||||
const float ATTENUATION_AMOUNT_PER_DOUBLING_IN_DISTANCE = 0.18f;
|
|
||||||
const float RADIUS_OF_HEAD = 0.076f;
|
const float RADIUS_OF_HEAD = 0.076f;
|
||||||
|
|
||||||
int AudioMixer::addStreamToMixForListeningNodeWithStream(AudioMixerClientData* listenerNodeData,
|
int AudioMixer::addStreamToMixForListeningNodeWithStream(AudioMixerClientData* listenerNodeData,
|
||||||
|
@ -210,7 +211,7 @@ int AudioMixer::addStreamToMixForListeningNodeWithStream(AudioMixerClientData* l
|
||||||
if (shouldDistanceAttenuate && (distanceBetween >= ATTENUATION_BEGINS_AT_DISTANCE)) {
|
if (shouldDistanceAttenuate && (distanceBetween >= ATTENUATION_BEGINS_AT_DISTANCE)) {
|
||||||
// calculate the distance coefficient using the distance to this node
|
// calculate the distance coefficient using the distance to this node
|
||||||
float distanceCoefficient = 1 - (logf(distanceBetween / ATTENUATION_BEGINS_AT_DISTANCE) / logf(2.0f)
|
float distanceCoefficient = 1 - (logf(distanceBetween / ATTENUATION_BEGINS_AT_DISTANCE) / logf(2.0f)
|
||||||
* ATTENUATION_AMOUNT_PER_DOUBLING_IN_DISTANCE);
|
* _attenuationPerDoublingInDistance);
|
||||||
|
|
||||||
if (distanceCoefficient < 0) {
|
if (distanceCoefficient < 0) {
|
||||||
distanceCoefficient = 0;
|
distanceCoefficient = 0;
|
||||||
|
@ -740,6 +741,16 @@ void AudioMixer::run() {
|
||||||
qDebug() << "Buffers inside this zone will not be attenuated inside a box with center at"
|
qDebug() << "Buffers inside this zone will not be attenuated inside a box with center at"
|
||||||
<< QString("%1, %2, %3").arg(destinationCenter.x).arg(destinationCenter.y).arg(destinationCenter.z);
|
<< QString("%1, %2, %3").arg(destinationCenter.x).arg(destinationCenter.y).arg(destinationCenter.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString ATTENATION_PER_DOULING_IN_DISTANCE = "attenuation_per_doubling_in_distance";
|
||||||
|
if (audioGroupObject[ATTENATION_PER_DOULING_IN_DISTANCE].isString()) {
|
||||||
|
bool ok = false;
|
||||||
|
float attenuation = audioGroupObject[ATTENATION_PER_DOULING_IN_DISTANCE].toString().toFloat(&ok);
|
||||||
|
if (ok) {
|
||||||
|
_attenuationPerDoublingInDistance = attenuation;
|
||||||
|
qDebug() << "Attenuation per doubling in distance changed to" << _attenuationPerDoublingInDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int nextFrame = 0;
|
int nextFrame = 0;
|
||||||
|
|
|
@ -69,6 +69,7 @@ private:
|
||||||
float _trailingSleepRatio;
|
float _trailingSleepRatio;
|
||||||
float _minAudibilityThreshold;
|
float _minAudibilityThreshold;
|
||||||
float _performanceThrottlingRatio;
|
float _performanceThrottlingRatio;
|
||||||
|
float _attenuationPerDoublingInDistance;
|
||||||
int _numStatFrames;
|
int _numStatFrames;
|
||||||
int _sumListeners;
|
int _sumListeners;
|
||||||
int _sumMixes;
|
int _sumMixes;
|
||||||
|
|
|
@ -72,6 +72,14 @@
|
||||||
"help": "Boxes for source and listener (corner x, corner y, corner z, size x, size y, size z, corner x, corner y, corner z, size x, size y, size z)",
|
"help": "Boxes for source and listener (corner x, corner y, corner z, size x, size y, size z, corner x, corner y, corner z, size x, size y, size z)",
|
||||||
"placeholder": "no zone"
|
"placeholder": "no zone"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "attenuation_per_doubling_in_distance",
|
||||||
|
"label": "Attenuattion per doubling in distance",
|
||||||
|
"help": "Factor between 0.0 and 1.0 (0.0: No attenuation, 1.0: extreme attenuation)",
|
||||||
|
"placeholder": "0.18",
|
||||||
|
"default": "0.18",
|
||||||
|
"advanced": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dynamic_jitter_buffer",
|
"name": "dynamic_jitter_buffer",
|
||||||
"type": "checkbox",
|
"type": "checkbox",
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<pre id='editor' style='font-size: 14px;'><!--#include file="placeholder.js"--></object></pre>
|
<pre id='editor' style='font-size: 14px;'><!--#include file="placeholder.js"--></object></pre>
|
||||||
<script src='../js/jquery-2.0.3.min.js'></script>
|
<script src='../js/jquery.min.js'></script>
|
||||||
<script src='js/ace/ace.js' type='text/javascript'></script>
|
<script src='js/ace/ace.js' type='text/javascript'></script>
|
||||||
<script src='js/assignment.js' type='text/javascript'></script>
|
<script src='js/assignment.js' type='text/javascript'></script>
|
||||||
<div class='big-button' id='deploy-button'>
|
<div class='big-button' id='deploy-button'>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
</div>
|
</div>
|
||||||
<script src='/js/jquery-2.1.1.min.js'></script>
|
<script src='/js/jquery.min.js'></script>
|
||||||
<script src='/js/bootstrap.min.js'></script>
|
<script src='/js/bootstrap.min.js'></script>
|
||||||
<script src='/js/domain-server.js'></script>
|
<script src='/js/domain-server.js'></script>
|
|
@ -158,6 +158,8 @@ $('body').on('click', '.save-button', function(e){
|
||||||
// grab a JSON representation of the form via form2js
|
// grab a JSON representation of the form via form2js
|
||||||
var formJSON = form2js('settings-form', ".", false, cleanupFormValues, true);
|
var formJSON = form2js('settings-form', ".", false, cleanupFormValues, true);
|
||||||
|
|
||||||
|
console.log(formJSON);
|
||||||
|
|
||||||
// re-enable all inputs
|
// re-enable all inputs
|
||||||
$("input").each(function(){
|
$("input").each(function(){
|
||||||
$(this).prop('disabled', false);
|
$(this).prop('disabled', false);
|
||||||
|
@ -237,7 +239,7 @@ function showRestartModal() {
|
||||||
|
|
||||||
function cleanupFormValues(node) {
|
function cleanupFormValues(node) {
|
||||||
if (node.type && node.type === 'checkbox') {
|
if (node.type && node.type === 'checkbox') {
|
||||||
return { name: node.id, value: node.checked ? true : false };
|
return { name: node.name, value: node.checked ? true : false };
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,11 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
|
|
||||||
void DomainServer::restart() {
|
void DomainServer::restart() {
|
||||||
qDebug() << "domain-server is restarting.";
|
qDebug() << "domain-server is restarting.";
|
||||||
|
|
||||||
|
// make sure all static instances are reset
|
||||||
|
LimitedNodeList::getInstance()->reset();
|
||||||
|
AccountManager::getInstance(true);
|
||||||
|
|
||||||
exit(DomainServer::EXIT_CODE_REBOOT);
|
exit(DomainServer::EXIT_CODE_REBOOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2745,7 +2745,7 @@ function setupModelMenus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Paste Models", shortcutKey: "CTRL+META+V", afterItem: "Edit Properties..." });
|
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Paste Models", shortcutKey: "CTRL+META+V", afterItem: "Edit Properties..." });
|
||||||
|
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Model List", afterItem: "Models" });
|
||||||
Menu.addMenuItem({ menuName: "File", menuItemName: "Models", isSeparator: true, beforeItem: "Settings" });
|
Menu.addMenuItem({ menuName: "File", menuItemName: "Models", isSeparator: true, beforeItem: "Settings" });
|
||||||
Menu.addMenuItem({ menuName: "File", menuItemName: "Export Models", shortcutKey: "CTRL+META+E", afterItem: "Models" });
|
Menu.addMenuItem({ menuName: "File", menuItemName: "Export Models", shortcutKey: "CTRL+META+E", afterItem: "Models" });
|
||||||
Menu.addMenuItem({ menuName: "File", menuItemName: "Import Models", shortcutKey: "CTRL+META+I", afterItem: "Export Models" });
|
Menu.addMenuItem({ menuName: "File", menuItemName: "Import Models", shortcutKey: "CTRL+META+I", afterItem: "Export Models" });
|
||||||
|
@ -2796,6 +2796,128 @@ var dimensionY;
|
||||||
var dimensionZ;
|
var dimensionZ;
|
||||||
var rescalePercentage;
|
var rescalePercentage;
|
||||||
|
|
||||||
|
function showPropertiesForm() {
|
||||||
|
propertiesForEditedEntity = Entities.getEntityProperties(editModelID);
|
||||||
|
var properties = propertiesForEditedEntity;
|
||||||
|
|
||||||
|
var array = new Array();
|
||||||
|
var index = 0;
|
||||||
|
var decimals = 3;
|
||||||
|
if (properties.type == "Model") {
|
||||||
|
array.push({ label: "Model URL:", value: properties.modelURL });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Animation URL:", value: properties.animationURL });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Animation is playing:", value: properties.animationIsPlaying });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Animation FPS:", value: properties.animationFPS });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Animation Frame:", value: properties.animationFrameIndex });
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
array.push({ label: "Position:", type: "header" });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "X:", value: properties.position.x.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Y:", value: properties.position.y.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Z:", value: properties.position.z.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
|
||||||
|
array.push({ label: "Registration X:", value: properties.registrationPoint.x.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Registration Y:", value: properties.registrationPoint.y.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Registration Z:", value: properties.registrationPoint.z.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
|
||||||
|
array.push({ label: "Rotation:", type: "header" });
|
||||||
|
index++;
|
||||||
|
var angles = Quat.safeEulerAngles(properties.rotation);
|
||||||
|
array.push({ label: "Pitch:", value: angles.x.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Yaw:", value: angles.y.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Roll:", value: angles.z.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
|
||||||
|
array.push({ label: "Dimensions:", type: "header" });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Width:", value: properties.dimensions.x.toFixed(decimals) });
|
||||||
|
dimensionX = index;
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Height:", value: properties.dimensions.y.toFixed(decimals) });
|
||||||
|
dimensionY = index;
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Depth:", value: properties.dimensions.z.toFixed(decimals) });
|
||||||
|
dimensionZ = index;
|
||||||
|
index++;
|
||||||
|
array.push({ label: "", type: "inlineButton", buttonLabel: "Reset to Natural Dimensions", name: "resetDimensions" });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Rescale Percentage:", value: 100 });
|
||||||
|
rescalePercentage = index;
|
||||||
|
index++;
|
||||||
|
array.push({ label: "", type: "inlineButton", buttonLabel: "Rescale", name: "rescaleDimensions" });
|
||||||
|
index++;
|
||||||
|
|
||||||
|
array.push({ label: "Velocity:", type: "header" });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Linear X:", value: properties.velocity.x.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Linear Y:", value: properties.velocity.y.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Linear Z:", value: properties.velocity.z.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Linear Damping:", value: properties.damping.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Angular Pitch:", value: properties.angularVelocity.x.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Angular Yaw:", value: properties.angularVelocity.y.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Angular Roll:", value: properties.angularVelocity.z.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Angular Damping:", value: properties.angularDamping.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
|
||||||
|
array.push({ label: "Gravity X:", value: properties.gravity.x.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Gravity Y:", value: properties.gravity.y.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Gravity Z:", value: properties.gravity.z.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
|
||||||
|
array.push({ label: "Collisions:", type: "header" });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Mass:", value: properties.mass.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Ignore for Collisions:", value: properties.ignoreForCollisions });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Collisions Will Move:", value: properties.collisionsWillMove });
|
||||||
|
index++;
|
||||||
|
|
||||||
|
array.push({ label: "Lifetime:", value: properties.lifetime.toFixed(decimals) });
|
||||||
|
index++;
|
||||||
|
|
||||||
|
array.push({ label: "Visible:", value: properties.visible });
|
||||||
|
index++;
|
||||||
|
|
||||||
|
if (properties.type == "Box" || properties.type == "Sphere") {
|
||||||
|
array.push({ label: "Color:", type: "header" });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Red:", value: properties.color.red });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Green:", value: properties.color.green });
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Blue:", value: properties.color.blue });
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
array.push({ button: "Cancel" });
|
||||||
|
index++;
|
||||||
|
|
||||||
|
editEntityFormArray = array;
|
||||||
|
Window.nonBlockingForm("Edit Properties", array);
|
||||||
|
}
|
||||||
|
|
||||||
function handeMenuEvent(menuItem) {
|
function handeMenuEvent(menuItem) {
|
||||||
print("menuItemEvent() in JS... menuItem=" + menuItem);
|
print("menuItemEvent() in JS... menuItem=" + menuItem);
|
||||||
if (menuItem == "Delete") {
|
if (menuItem == "Delete") {
|
||||||
|
@ -2823,6 +2945,33 @@ function handeMenuEvent(menuItem) {
|
||||||
} else {
|
} else {
|
||||||
print(" Delete Entity.... not holding...");
|
print(" Delete Entity.... not holding...");
|
||||||
}
|
}
|
||||||
|
} else if (menuItem == "Model List") {
|
||||||
|
var models = new Array();
|
||||||
|
models = Entities.findEntities(MyAvatar.position, Number.MAX_VALUE);
|
||||||
|
for (var i = 0; i < models.length; i++) {
|
||||||
|
models[i].properties = Entities.getEntityProperties(models[i]);
|
||||||
|
models[i].toString = function() {
|
||||||
|
var modelname = decodeURIComponent(
|
||||||
|
this.properties.modelURL.indexOf("/") != -1 ?
|
||||||
|
this.properties.modelURL.substring(this.properties.modelURL.lastIndexOf("/") + 1) :
|
||||||
|
this.properties.modelURL);
|
||||||
|
return "[" + this.properties.type + "] " + modelname;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var form = [{label: "Model: ", options: models}];
|
||||||
|
form.push({label: "Action: ", options: ["Properties", "Delete", "Teleport"]});
|
||||||
|
form.push({ button: "Cancel" });
|
||||||
|
if (Window.form("Model List", form)) {
|
||||||
|
var selectedModel = form[0].value;
|
||||||
|
if (form[1].value == "Properties") {
|
||||||
|
editModelID = selectedModel;
|
||||||
|
showPropertiesForm();
|
||||||
|
} else if (form[1].value == "Delete") {
|
||||||
|
Entities.deleteEntity(selectedModel);
|
||||||
|
} else if (form[1].value == "Teleport") {
|
||||||
|
MyAvatar.position = selectedModel.properties.position;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (menuItem == "Edit Properties...") {
|
} else if (menuItem == "Edit Properties...") {
|
||||||
editModelID = -1;
|
editModelID = -1;
|
||||||
if (leftController.grabbing) {
|
if (leftController.grabbing) {
|
||||||
|
@ -2839,126 +2988,7 @@ function handeMenuEvent(menuItem) {
|
||||||
}
|
}
|
||||||
if (editModelID != -1) {
|
if (editModelID != -1) {
|
||||||
print(" Edit Properties.... about to edit properties...");
|
print(" Edit Properties.... about to edit properties...");
|
||||||
|
showPropertiesForm(editModelID);
|
||||||
propertiesForEditedEntity = Entities.getEntityProperties(editModelID);
|
|
||||||
var properties = propertiesForEditedEntity;
|
|
||||||
|
|
||||||
var array = new Array();
|
|
||||||
var index = 0;
|
|
||||||
var decimals = 3;
|
|
||||||
if (properties.type == "Model") {
|
|
||||||
array.push({ label: "Model URL:", value: properties.modelURL });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Animation URL:", value: properties.animationURL });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Animation is playing:", value: properties.animationIsPlaying });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Animation FPS:", value: properties.animationFPS });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Animation Frame:", value: properties.animationFrameIndex });
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
array.push({ label: "Position:", type: "header" });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "X:", value: properties.position.x.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Y:", value: properties.position.y.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Z:", value: properties.position.z.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
|
|
||||||
array.push({ label: "Registration X:", value: properties.registrationPoint.x.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Registration Y:", value: properties.registrationPoint.y.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Registration Z:", value: properties.registrationPoint.z.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
|
|
||||||
array.push({ label: "Rotation:", type: "header" });
|
|
||||||
index++;
|
|
||||||
var angles = Quat.safeEulerAngles(properties.rotation);
|
|
||||||
array.push({ label: "Pitch:", value: angles.x.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Yaw:", value: angles.y.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Roll:", value: angles.z.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
|
|
||||||
array.push({ label: "Dimensions:", type: "header" });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Width:", value: properties.dimensions.x.toFixed(decimals) });
|
|
||||||
dimensionX = index;
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Height:", value: properties.dimensions.y.toFixed(decimals) });
|
|
||||||
dimensionY = index;
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Depth:", value: properties.dimensions.z.toFixed(decimals) });
|
|
||||||
dimensionZ = index;
|
|
||||||
index++;
|
|
||||||
array.push({ label: "", type: "inlineButton", buttonLabel: "Reset to Natural Dimensions", name: "resetDimensions" });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Rescale Percentage:", value: 100 });
|
|
||||||
rescalePercentage = index;
|
|
||||||
index++;
|
|
||||||
array.push({ label: "", type: "inlineButton", buttonLabel: "Rescale", name: "rescaleDimensions" });
|
|
||||||
index++;
|
|
||||||
|
|
||||||
array.push({ label: "Velocity:", type: "header" });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Linear X:", value: properties.velocity.x.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Linear Y:", value: properties.velocity.y.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Linear Z:", value: properties.velocity.z.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Linear Damping:", value: properties.damping.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Angular Pitch:", value: properties.angularVelocity.x.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Angular Yaw:", value: properties.angularVelocity.y.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Angular Roll:", value: properties.angularVelocity.z.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Angular Damping:", value: properties.angularDamping.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
|
|
||||||
array.push({ label: "Gravity X:", value: properties.gravity.x.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Gravity Y:", value: properties.gravity.y.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Gravity Z:", value: properties.gravity.z.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
|
|
||||||
array.push({ label: "Collisions:", type: "header" });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Mass:", value: properties.mass.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Ignore for Collisions:", value: properties.ignoreForCollisions });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Collisions Will Move:", value: properties.collisionsWillMove });
|
|
||||||
index++;
|
|
||||||
|
|
||||||
array.push({ label: "Lifetime:", value: properties.lifetime.toFixed(decimals) });
|
|
||||||
index++;
|
|
||||||
|
|
||||||
array.push({ label: "Visible:", value: properties.visible });
|
|
||||||
index++;
|
|
||||||
|
|
||||||
if (properties.type == "Box" || properties.type == "Sphere") {
|
|
||||||
array.push({ label: "Color:", type: "header" });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Red:", value: properties.color.red });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Green:", value: properties.color.green });
|
|
||||||
index++;
|
|
||||||
array.push({ label: "Blue:", value: properties.color.blue });
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
array.push({ button: "Cancel" });
|
|
||||||
index++;
|
|
||||||
|
|
||||||
editEntityFormArray = array;
|
|
||||||
Window.nonBlockingForm("Edit Properties", array);
|
|
||||||
}
|
}
|
||||||
} else if (menuItem == "Paste Models") {
|
} else if (menuItem == "Paste Models") {
|
||||||
modelImporter.paste();
|
modelImporter.paste();
|
||||||
|
|
|
@ -13,7 +13,10 @@
|
||||||
|
|
||||||
var leapHands = (function () {
|
var leapHands = (function () {
|
||||||
|
|
||||||
var hands,
|
var isOnHMD,
|
||||||
|
LEAP_OFFSET = 0.019, // Thickness of Leap Motion plus HMD clip
|
||||||
|
HMD_OFFSET = 0.100, // Eyeballs to front surface of Oculus DK2 TODO: Confirm and make depend on device and eye relief
|
||||||
|
hands,
|
||||||
wrists,
|
wrists,
|
||||||
NUM_HANDS = 2, // 0 = left; 1 = right
|
NUM_HANDS = 2, // 0 = left; 1 = right
|
||||||
fingers,
|
fingers,
|
||||||
|
@ -188,8 +191,6 @@ var leapHands = (function () {
|
||||||
|
|
||||||
function setUp() {
|
function setUp() {
|
||||||
|
|
||||||
calibrationStatus = UNCALIBRATED;
|
|
||||||
|
|
||||||
// TODO: Leap Motion controller joint naming doesn't match up with skeleton joint naming; numbers are out by 1.
|
// TODO: Leap Motion controller joint naming doesn't match up with skeleton joint naming; numbers are out by 1.
|
||||||
|
|
||||||
hands = [
|
hands = [
|
||||||
|
@ -265,6 +266,20 @@ var leapHands = (function () {
|
||||||
{ jointName: "RightHandPinky3", controller: Controller.createInputController("Spatial", "joint_R_pinky4") }
|
{ jointName: "RightHandPinky3", controller: Controller.createInputController("Spatial", "joint_R_pinky4") }
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
isOnHMD = Menu.isOptionChecked("Leap Motion on HMD");
|
||||||
|
if (isOnHMD) {
|
||||||
|
print("Leap Motion is on HMD");
|
||||||
|
|
||||||
|
// Offset of Leap Motion origin from physical eye position
|
||||||
|
hands[0].zeroPosition = { x: 0.0, y: 0.0, z: HMD_OFFSET + LEAP_OFFSET };
|
||||||
|
hands[1].zeroPosition = { x: 0.0, y: 0.0, z: HMD_OFFSET + LEAP_OFFSET };
|
||||||
|
|
||||||
|
calibrationStatus = CALIBRATED;
|
||||||
|
} else {
|
||||||
|
print("Leap Motion is on desk");
|
||||||
|
calibrationStatus = UNCALIBRATED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveHands() {
|
function moveHands() {
|
||||||
|
@ -278,7 +293,9 @@ var leapHands = (function () {
|
||||||
handYaw,
|
handYaw,
|
||||||
handRotation,
|
handRotation,
|
||||||
wristAbsRotation,
|
wristAbsRotation,
|
||||||
locRotation;
|
locRotation,
|
||||||
|
cameraOrientation,
|
||||||
|
inverseAvatarOrientation;
|
||||||
|
|
||||||
for (h = 0; h < NUM_HANDS; h += 1) {
|
for (h = 0; h < NUM_HANDS; h += 1) {
|
||||||
side = h === 0 ? -1.0 : 1.0;
|
side = h === 0 ? -1.0 : 1.0;
|
||||||
|
@ -291,35 +308,82 @@ var leapHands = (function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hand position ...
|
// Hand position ...
|
||||||
handOffset = hands[h].controller.getAbsTranslation();
|
if (isOnHMD) {
|
||||||
handOffset = {
|
|
||||||
x: -handOffset.x,
|
|
||||||
y: hands[h].zeroPosition.y + handOffset.y,
|
|
||||||
z: hands[h].zeroPosition.z - handOffset.z
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: 2.0* scale factor should not be necessary; Leap Motion controller code needs investigating.
|
// Hand offset in camera coordinates ...
|
||||||
handRoll = 2.0 * -hands[h].controller.getAbsRotation().z;
|
handOffset = hands[h].controller.getAbsTranslation();
|
||||||
wristAbsRotation = wrists[h].controller.getAbsRotation();
|
handOffset = {
|
||||||
handPitch = 2.0 * -wristAbsRotation.x;
|
x: hands[h].zeroPosition.x - handOffset.x,
|
||||||
handYaw = 2.0 * wristAbsRotation.y;
|
y: hands[h].zeroPosition.y - handOffset.z,
|
||||||
|
z: hands[h].zeroPosition.z + handOffset.y
|
||||||
|
};
|
||||||
|
handOffset.z = -handOffset.z;
|
||||||
|
|
||||||
// TODO: Leap Motion controller's right-hand roll calculation only works if physical hand is upside down.
|
// Hand offset in world coordinates ...
|
||||||
// Approximate fix is to add a fudge factor.
|
cameraOrientation = Camera.getOrientation();
|
||||||
if (h === 1 && isWindows) {
|
handOffset = Vec3.sum(Camera.getPosition(), Vec3.multiplyQbyV(cameraOrientation, handOffset));
|
||||||
handRoll = handRoll + 0.6 * PI;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hand position and orientation ...
|
// Hand offset in avatar coordinates ...
|
||||||
if (h === 0) {
|
inverseAvatarOrientation = Quat.inverse(MyAvatar.orientation);
|
||||||
handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 1, z: 0 }),
|
handOffset = Vec3.subtract(handOffset, MyAvatar.position);
|
||||||
Quat.fromVec3Radians({ x: handRoll, y: handYaw, z: -handPitch }));
|
handOffset = Vec3.multiplyQbyV(inverseAvatarOrientation, handOffset);
|
||||||
|
handOffset.z = -handOffset.z;
|
||||||
|
handOffset.x = -handOffset.x;
|
||||||
|
|
||||||
|
// Hand rotation in camera coordinates ...
|
||||||
|
// TODO: 2.0* scale factors should not be necessary; Leap Motion controller code needs investigating.
|
||||||
|
handRoll = 2.0 * -hands[h].controller.getAbsRotation().z;
|
||||||
|
wristAbsRotation = wrists[h].controller.getAbsRotation();
|
||||||
|
handPitch = 2.0 * wristAbsRotation.x - PI / 2.0;
|
||||||
|
handYaw = 2.0 * -wristAbsRotation.y;
|
||||||
|
// TODO: Roll values only work if hand is upside down; Leap Motion controller code needs investigating.
|
||||||
|
handRoll = PI + handRoll;
|
||||||
|
|
||||||
|
if (h === 0) {
|
||||||
|
handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 1, z: 0 }),
|
||||||
|
Quat.fromVec3Radians({ x: handRoll, y: handYaw, z: -handPitch }));
|
||||||
|
} else {
|
||||||
|
handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 0, y: 1, z: 0 }),
|
||||||
|
Quat.fromVec3Radians({ x: -handRoll, y: handYaw, z: handPitch }));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hand rotation in avatar coordinates ...
|
||||||
|
cameraOrientation.x = -cameraOrientation.x;
|
||||||
|
cameraOrientation.z = -cameraOrientation.z;
|
||||||
|
handRotation = Quat.multiply(cameraOrientation, handRotation);
|
||||||
|
handRotation = Quat.multiply(inverseAvatarOrientation, handRotation);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 0, y: 1, z: 0 }),
|
|
||||||
Quat.fromVec3Radians({ x: -handRoll, y: handYaw, z: handPitch }));
|
handOffset = hands[h].controller.getAbsTranslation();
|
||||||
|
handOffset = {
|
||||||
|
x: -handOffset.x,
|
||||||
|
y: hands[h].zeroPosition.y + handOffset.y,
|
||||||
|
z: hands[h].zeroPosition.z - handOffset.z
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: 2.0* scale factors should not be necessary; Leap Motion controller code needs investigating.
|
||||||
|
handRoll = 2.0 * -hands[h].controller.getAbsRotation().z;
|
||||||
|
wristAbsRotation = wrists[h].controller.getAbsRotation();
|
||||||
|
handPitch = 2.0 * -wristAbsRotation.x;
|
||||||
|
handYaw = 2.0 * wristAbsRotation.y;
|
||||||
|
|
||||||
|
// TODO: Leap Motion controller's right-hand roll calculation only works if physical hand is upside down.
|
||||||
|
// Approximate fix is to add a fudge factor.
|
||||||
|
if (h === 1 && isWindows) {
|
||||||
|
handRoll = handRoll + 0.6 * PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hand position and orientation ...
|
||||||
|
if (h === 0) {
|
||||||
|
handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 1, z: 0 }),
|
||||||
|
Quat.fromVec3Radians({ x: handRoll, y: handYaw, z: -handPitch }));
|
||||||
|
} else {
|
||||||
|
handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 0, y: 1, z: 0 }),
|
||||||
|
Quat.fromVec3Radians({ x: -handRoll, y: handYaw, z: handPitch }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MyAvatar.setJointModelPositionAndOrientation(hands[h].jointName, handOffset, handRotation, true);
|
MyAvatar.setJointModelPositionAndOrientation(hands[h].jointName, handOffset, handRotation, true);
|
||||||
|
|
||||||
// Finger joints ...
|
// Finger joints ...
|
||||||
|
|
|
@ -599,8 +599,11 @@ void Application::paintGL() {
|
||||||
|
|
||||||
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
|
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
|
||||||
_myCamera.setTightness(0.0f); // In first person, camera follows (untweaked) head exactly without delay
|
_myCamera.setTightness(0.0f); // In first person, camera follows (untweaked) head exactly without delay
|
||||||
_myCamera.setTargetPosition(_myAvatar->getHead()->getEyePosition());
|
if (!OculusManager::isConnected()) {
|
||||||
_myCamera.setTargetRotation(_myAvatar->getHead()->getCameraOrientation());
|
_myCamera.setTargetPosition(_myAvatar->getHead()->getEyePosition());
|
||||||
|
_myCamera.setTargetRotation(_myAvatar->getHead()->getCameraOrientation());
|
||||||
|
}
|
||||||
|
// OculusManager::display() updates camera position and rotation a bit further on.
|
||||||
|
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||||
//Note, the camera distance is set in Camera::setMode() so we dont have to do it here.
|
//Note, the camera distance is set in Camera::setMode() so we dont have to do it here.
|
||||||
|
@ -630,7 +633,9 @@ void Application::paintGL() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update camera position
|
// Update camera position
|
||||||
_myCamera.update( 1.f/_fps );
|
if (!OculusManager::isConnected()) {
|
||||||
|
_myCamera.update(1.f / _fps);
|
||||||
|
}
|
||||||
|
|
||||||
// Note: whichCamera is used to pick between the normal camera myCamera for our
|
// Note: whichCamera is used to pick between the normal camera myCamera for our
|
||||||
// main camera, vs, an alternate camera. The alternate camera we support right now
|
// main camera, vs, an alternate camera. The alternate camera we support right now
|
||||||
|
@ -640,7 +645,7 @@ void Application::paintGL() {
|
||||||
// Why have two cameras? Well, one reason is that because in the case of the renderViewFrustum()
|
// Why have two cameras? Well, one reason is that because in the case of the renderViewFrustum()
|
||||||
// code, we want to keep the state of "myCamera" intact, so we can render what the view frustum of
|
// code, we want to keep the state of "myCamera" intact, so we can render what the view frustum of
|
||||||
// myCamera is. But we also want to do meaningful camera transforms on OpenGL for the offset camera
|
// myCamera is. But we also want to do meaningful camera transforms on OpenGL for the offset camera
|
||||||
Camera whichCamera = _myCamera;
|
Camera* whichCamera = &_myCamera;
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum)) {
|
||||||
|
|
||||||
|
@ -654,7 +659,7 @@ void Application::paintGL() {
|
||||||
_viewFrustumOffsetCamera.setDistance(viewFrustumOffset.distance);
|
_viewFrustumOffsetCamera.setDistance(viewFrustumOffset.distance);
|
||||||
_viewFrustumOffsetCamera.initialize(); // force immediate snap to ideal position and orientation
|
_viewFrustumOffsetCamera.initialize(); // force immediate snap to ideal position and orientation
|
||||||
_viewFrustumOffsetCamera.update(1.f/_fps);
|
_viewFrustumOffsetCamera.update(1.f/_fps);
|
||||||
whichCamera = _viewFrustumOffsetCamera;
|
whichCamera = &_viewFrustumOffsetCamera;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Menu::getInstance()->getShadowsEnabled()) {
|
if (Menu::getInstance()->getShadowsEnabled()) {
|
||||||
|
@ -667,15 +672,16 @@ void Application::paintGL() {
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
//When in mirror mode, use camera rotation. Otherwise, use body rotation
|
//When in mirror mode, use camera rotation. Otherwise, use body rotation
|
||||||
if (whichCamera.getMode() == CAMERA_MODE_MIRROR) {
|
if (whichCamera->getMode() == CAMERA_MODE_MIRROR) {
|
||||||
OculusManager::display(whichCamera.getRotation(), whichCamera.getPosition(), whichCamera);
|
OculusManager::display(whichCamera->getRotation(), whichCamera->getPosition(), *whichCamera);
|
||||||
} else {
|
} else {
|
||||||
OculusManager::display(_myAvatar->getWorldAlignedOrientation(), _myAvatar->getDefaultEyePosition(), whichCamera);
|
OculusManager::display(_myAvatar->getWorldAlignedOrientation(), _myAvatar->getDefaultEyePosition(), *whichCamera);
|
||||||
}
|
}
|
||||||
|
_myCamera.update(1.f / _fps);
|
||||||
|
|
||||||
} else if (TV3DManager::isConnected()) {
|
} else if (TV3DManager::isConnected()) {
|
||||||
|
|
||||||
TV3DManager::display(whichCamera);
|
TV3DManager::display(*whichCamera);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_glowEffect.prepare();
|
_glowEffect.prepare();
|
||||||
|
@ -683,7 +689,7 @@ void Application::paintGL() {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
displaySide(whichCamera);
|
displaySide(*whichCamera);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
||||||
|
|
|
@ -453,6 +453,9 @@ Menu::Menu() :
|
||||||
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseMouseInput, 0, true);
|
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseMouseInput, 0, true);
|
||||||
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseLasers, 0, false);
|
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseLasers, 0, false);
|
||||||
|
|
||||||
|
QMenu* leapOptionsMenu = handOptionsMenu->addMenu("Leap Motion");
|
||||||
|
addCheckableActionToQMenuAndActionHash(leapOptionsMenu, MenuOption::LeapMotionOnHMD, 0, false);
|
||||||
|
|
||||||
QMenu* networkMenu = developerMenu->addMenu("Network");
|
QMenu* networkMenu = developerMenu->addMenu("Network");
|
||||||
addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableNackPackets, 0, false);
|
addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableNackPackets, 0, false);
|
||||||
addCheckableActionToQMenuAndActionHash(networkMenu,
|
addCheckableActionToQMenuAndActionHash(networkMenu,
|
||||||
|
|
|
@ -403,6 +403,7 @@ namespace MenuOption {
|
||||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||||
const QString IncreaseVoxelSize = "Increase Voxel Size";
|
const QString IncreaseVoxelSize = "Increase Voxel Size";
|
||||||
const QString KeyboardMotorControl = "Enable Keyboard Motor Control";
|
const QString KeyboardMotorControl = "Enable Keyboard Motor Control";
|
||||||
|
const QString LeapMotionOnHMD = "Leap Motion on HMD";
|
||||||
const QString LoadScript = "Open and Run Script File...";
|
const QString LoadScript = "Open and Run Script File...";
|
||||||
const QString LoadScriptURL = "Open and Run Script from URL...";
|
const QString LoadScriptURL = "Open and Run Script from URL...";
|
||||||
const QString LodTools = "LOD Tools";
|
const QString LodTools = "LOD Tools";
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
#include "SharedUtil.h"
|
|
||||||
#include "Leapmotion.h"
|
#include "Leapmotion.h"
|
||||||
|
#include "Menu.h"
|
||||||
|
#include "SharedUtil.h"
|
||||||
|
|
||||||
const int PALMROOT_NUM_JOINTS = 3;
|
const int PALMROOT_NUM_JOINTS = 3;
|
||||||
const int FINGER_NUM_JOINTS = 4;
|
const int FINGER_NUM_JOINTS = 4;
|
||||||
|
@ -101,6 +102,12 @@ Leapmotion::Leapmotion() :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LEAPMOTION
|
||||||
|
if (Menu::getInstance()->isOptionChecked(MenuOption::LeapMotionOnHMD)) {
|
||||||
|
_controller.setPolicyFlags(Leap::Controller::POLICY_OPTIMIZE_HMD);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Leapmotion::~Leapmotion() {
|
Leapmotion::~Leapmotion() {
|
||||||
|
|
|
@ -412,6 +412,10 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
// Update camera for use by rest of Interface.
|
||||||
|
whichCamera.setTargetPosition((_leftEyePosition + _rightEyePosition) / 2.f);
|
||||||
|
whichCamera.setTargetRotation(_camera->getTargetRotation());
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ SixenseManager& SixenseManager::getInstance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
SixenseManager::SixenseManager() :
|
SixenseManager::SixenseManager() :
|
||||||
#ifdef __APPLE__
|
#if defined(HAVE_SIXENSE) && defined(__APPLE__)
|
||||||
_sixenseLibrary(NULL),
|
_sixenseLibrary(NULL),
|
||||||
#endif
|
#endif
|
||||||
_isInitialized(false),
|
_isInitialized(false),
|
||||||
|
|
|
@ -265,7 +265,11 @@ QScriptValue WindowScriptingInterface::doPeekNonBlockingFormResult(QScriptValue
|
||||||
_form.setProperty(i, item);
|
_form.setProperty(i, item);
|
||||||
} else if (item.property("options").isArray()) {
|
} else if (item.property("options").isArray()) {
|
||||||
c += 1;
|
c += 1;
|
||||||
item.setProperty("value", _combos.at(c)->currentText());
|
item.setProperty("value",
|
||||||
|
_combos.at(c)->currentIndex() < item.property("options").property("length").toInt32() ?
|
||||||
|
item.property("options").property(_combos.at(c)->currentIndex()) :
|
||||||
|
array.engine()->undefinedValue()
|
||||||
|
);
|
||||||
_form.setProperty(i, item);
|
_form.setProperty(i, item);
|
||||||
} else {
|
} else {
|
||||||
e += 1;
|
e += 1;
|
||||||
|
@ -318,7 +322,11 @@ QScriptValue WindowScriptingInterface::doGetNonBlockingFormResult(QScriptValue a
|
||||||
_form.setProperty(i, item);
|
_form.setProperty(i, item);
|
||||||
} else if (item.property("options").isArray()) {
|
} else if (item.property("options").isArray()) {
|
||||||
c += 1;
|
c += 1;
|
||||||
item.setProperty("value", _combos.at(c)->currentText());
|
item.setProperty("value",
|
||||||
|
_combos.at(c)->currentIndex() < item.property("options").property("length").toInt32() ?
|
||||||
|
item.property("options").property(_combos.at(c)->currentIndex()) :
|
||||||
|
array.engine()->undefinedValue()
|
||||||
|
);
|
||||||
_form.setProperty(i, item);
|
_form.setProperty(i, item);
|
||||||
} else {
|
} else {
|
||||||
e += 1;
|
e += 1;
|
||||||
|
@ -349,6 +357,7 @@ QScriptValue WindowScriptingInterface::doGetNonBlockingFormResult(QScriptValue a
|
||||||
_form = QScriptValue();
|
_form = QScriptValue();
|
||||||
_edits.clear();
|
_edits.clear();
|
||||||
_directories.clear();
|
_directories.clear();
|
||||||
|
_combos.clear();
|
||||||
|
|
||||||
array = _form;
|
array = _form;
|
||||||
return (_formResult == QDialog::Accepted);
|
return (_formResult == QDialog::Accepted);
|
||||||
|
@ -391,8 +400,12 @@ QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptVal
|
||||||
form.setProperty(i, item);
|
form.setProperty(i, item);
|
||||||
} else if (item.property("options").isArray()) {
|
} else if (item.property("options").isArray()) {
|
||||||
c += 1;
|
c += 1;
|
||||||
item.setProperty("value", _combos.at(c)->currentText());
|
item.setProperty("value",
|
||||||
_form.setProperty(i, item);
|
_combos.at(c)->currentIndex() < item.property("options").property("length").toInt32() ?
|
||||||
|
item.property("options").property(_combos.at(c)->currentIndex()) :
|
||||||
|
form.engine()->undefinedValue()
|
||||||
|
);
|
||||||
|
form.setProperty(i, item);
|
||||||
} else {
|
} else {
|
||||||
e += 1;
|
e += 1;
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
@ -418,6 +431,7 @@ QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptVal
|
||||||
}
|
}
|
||||||
|
|
||||||
delete editDialog;
|
delete editDialog;
|
||||||
|
_combos.clear();
|
||||||
_edits.clear();
|
_edits.clear();
|
||||||
_directories.clear();
|
_directories.clear();
|
||||||
return (result == QDialog::Accepted);
|
return (result == QDialog::Accepted);
|
||||||
|
@ -498,9 +512,9 @@ QDialog* WindowScriptingInterface::createForm(const QString& title, QScriptValue
|
||||||
} else if (item.property("options").isArray()) {
|
} else if (item.property("options").isArray()) {
|
||||||
QComboBox* combo = new QComboBox();
|
QComboBox* combo = new QComboBox();
|
||||||
combo->setMinimumWidth(200);
|
combo->setMinimumWidth(200);
|
||||||
QStringList options = item.property("options").toVariant().toStringList();
|
qint32 options_count = item.property("options").property("length").toInt32();
|
||||||
for (QStringList::const_iterator it = options.begin(); it != options.end(); it += 1) {
|
for (qint32 i = 0; i < options_count; i++) {
|
||||||
combo->addItem(*it);
|
combo->addItem(item.property("options").property(i).toString());
|
||||||
}
|
}
|
||||||
_combos.push_back(combo);
|
_combos.push_back(combo);
|
||||||
formLayout->addRow(new QLabel(item.property("label").toString()), combo);
|
formLayout->addRow(new QLabel(item.property("label").toString()), combo);
|
||||||
|
|
|
@ -96,6 +96,7 @@ void AudioInjector::injectAudio() {
|
||||||
packetStream << radius;
|
packetStream << radius;
|
||||||
|
|
||||||
// pack 255 for attenuation byte
|
// pack 255 for attenuation byte
|
||||||
|
int volumeOptionOffset = injectAudioPacket.size();
|
||||||
quint8 volume = MAX_INJECTOR_VOLUME * _options.getVolume();
|
quint8 volume = MAX_INJECTOR_VOLUME * _options.getVolume();
|
||||||
packetStream << volume;
|
packetStream << volume;
|
||||||
|
|
||||||
|
@ -118,6 +119,8 @@ void AudioInjector::injectAudio() {
|
||||||
memcpy(injectAudioPacket.data() + orientationOptionOffset,
|
memcpy(injectAudioPacket.data() + orientationOptionOffset,
|
||||||
&_options.getOrientation(),
|
&_options.getOrientation(),
|
||||||
sizeof(_options.getOrientation()));
|
sizeof(_options.getOrientation()));
|
||||||
|
volume = MAX_INJECTOR_VOLUME * _options.getVolume();
|
||||||
|
memcpy(injectAudioPacket.data() + volumeOptionOffset, &volume, sizeof(volume));
|
||||||
|
|
||||||
// resize the QByteArray to the right size
|
// resize the QByteArray to the right size
|
||||||
injectAudioPacket.resize(numPreAudioDataBytes + bytesToCopy);
|
injectAudioPacket.resize(numPreAudioDataBytes + bytesToCopy);
|
||||||
|
|
|
@ -652,13 +652,25 @@ void AvatarData::startPlaying() {
|
||||||
_player->startPlaying();
|
_player->startPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::setPlayerFrame(int frame) {
|
void AvatarData::setPlayerVolume(float volume) {
|
||||||
|
if (_player) {
|
||||||
|
_player->setVolume(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarData::setPlayerAudioOffset(int audioOffset) {
|
||||||
|
if (_player) {
|
||||||
|
_player->setAudioOffset(audioOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarData::setPlayerFrame(unsigned int frame) {
|
||||||
if (_player) {
|
if (_player) {
|
||||||
_player->setCurrentFrame(frame);
|
_player->setCurrentFrame(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::setPlayerTime(qint64 time) {
|
void AvatarData::setPlayerTime(unsigned int time) {
|
||||||
if (_player) {
|
if (_player) {
|
||||||
_player->setCurrentTime(time);
|
_player->setCurrentTime(time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,8 +100,6 @@ enum KeyState {
|
||||||
DELETE_KEY_DOWN
|
DELETE_KEY_DOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
const glm::vec3 vec3Zero(0.0f);
|
|
||||||
|
|
||||||
class QDataStream;
|
class QDataStream;
|
||||||
|
|
||||||
class AttachmentData;
|
class AttachmentData;
|
||||||
|
@ -304,8 +302,10 @@ public slots:
|
||||||
|
|
||||||
void loadRecording(QString filename);
|
void loadRecording(QString filename);
|
||||||
void startPlaying();
|
void startPlaying();
|
||||||
void setPlayerFrame(int frame);
|
void setPlayerVolume(float volume);
|
||||||
void setPlayerTime(qint64 time);
|
void setPlayerAudioOffset(int audioOffset);
|
||||||
|
void setPlayerFrame(unsigned int frame);
|
||||||
|
void setPlayerTime(unsigned int time);
|
||||||
void setPlayFromCurrentLocation(bool playFromCurrentLocation);
|
void setPlayFromCurrentLocation(bool playFromCurrentLocation);
|
||||||
void setPlayerLoop(bool loop);
|
void setPlayerLoop(bool loop);
|
||||||
void setPlayerUseDisplayName(bool useDisplayName);
|
void setPlayerUseDisplayName(bool useDisplayName);
|
||||||
|
|
|
@ -17,13 +17,16 @@
|
||||||
#include "AvatarData.h"
|
#include "AvatarData.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
|
|
||||||
|
static const int INVALID_FRAME = -1;
|
||||||
|
|
||||||
Player::Player(AvatarData* avatar) :
|
Player::Player(AvatarData* avatar) :
|
||||||
_recording(new Recording()),
|
|
||||||
_currentFrame(-1),
|
|
||||||
_frameInterpolationFactor(0.0f),
|
|
||||||
_pausedFrame(-1),
|
|
||||||
_timerOffset(0),
|
|
||||||
_avatar(avatar),
|
_avatar(avatar),
|
||||||
|
_recording(new Recording()),
|
||||||
|
_currentFrame(INVALID_FRAME),
|
||||||
|
_frameInterpolationFactor(0.0f),
|
||||||
|
_pausedFrame(INVALID_FRAME),
|
||||||
|
_timerOffset(0),
|
||||||
|
_audioOffset(0),
|
||||||
_audioThread(NULL),
|
_audioThread(NULL),
|
||||||
_playFromCurrentPosition(true),
|
_playFromCurrentPosition(true),
|
||||||
_loop(false),
|
_loop(false),
|
||||||
|
@ -33,8 +36,6 @@ Player::Player(AvatarData* avatar) :
|
||||||
_useSkeletonURL(true)
|
_useSkeletonURL(true)
|
||||||
{
|
{
|
||||||
_timer.invalidate();
|
_timer.invalidate();
|
||||||
_options.setLoop(false);
|
|
||||||
_options.setVolume(1.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::isPlaying() const {
|
bool Player::isPlaying() const {
|
||||||
|
@ -42,7 +43,7 @@ bool Player::isPlaying() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::isPaused() const {
|
bool Player::isPaused() const {
|
||||||
return (_pausedFrame != -1);
|
return (_pausedFrame != INVALID_FRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 Player::elapsed() const {
|
qint64 Player::elapsed() const {
|
||||||
|
@ -122,7 +123,7 @@ void Player::startPlaying() {
|
||||||
_timer.start();
|
_timer.start();
|
||||||
|
|
||||||
setCurrentFrame(_pausedFrame);
|
setCurrentFrame(_pausedFrame);
|
||||||
_pausedFrame = -1;
|
_pausedFrame = INVALID_FRAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +131,7 @@ void Player::stopPlaying() {
|
||||||
if (!isPlaying()) {
|
if (!isPlaying()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_pausedFrame = -1;
|
_pausedFrame = INVALID_FRAME;
|
||||||
_timer.invalidate();
|
_timer.invalidate();
|
||||||
cleanupAudioThread();
|
cleanupAudioThread();
|
||||||
_avatar->clearJointsData();
|
_avatar->clearJointsData();
|
||||||
|
@ -201,12 +202,12 @@ void Player::loadFromFile(const QString& file) {
|
||||||
}
|
}
|
||||||
readRecordingFromFile(_recording, file);
|
readRecordingFromFile(_recording, file);
|
||||||
|
|
||||||
_pausedFrame = -1;
|
_pausedFrame = INVALID_FRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::loadRecording(RecordingPointer recording) {
|
void Player::loadRecording(RecordingPointer recording) {
|
||||||
_recording = recording;
|
_recording = recording;
|
||||||
_pausedFrame = -1;
|
_pausedFrame = INVALID_FRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::play() {
|
void Player::play() {
|
||||||
|
@ -253,6 +254,9 @@ void Player::play() {
|
||||||
|
|
||||||
HeadData* head = const_cast<HeadData*>(_avatar->getHeadData());
|
HeadData* head = const_cast<HeadData*>(_avatar->getHeadData());
|
||||||
if (head) {
|
if (head) {
|
||||||
|
// Make sure fake faceshift connection doesn't get turned off
|
||||||
|
_avatar->setForceFaceshiftConnected(true);
|
||||||
|
|
||||||
QVector<float> blendCoef(currentFrame.getBlendshapeCoefficients().size());
|
QVector<float> blendCoef(currentFrame.getBlendshapeCoefficients().size());
|
||||||
for (int i = 0; i < currentFrame.getBlendshapeCoefficients().size(); ++i) {
|
for (int i = 0; i < currentFrame.getBlendshapeCoefficients().size(); ++i) {
|
||||||
blendCoef[i] = glm::mix(currentFrame.getBlendshapeCoefficients()[i],
|
blendCoef[i] = glm::mix(currentFrame.getBlendshapeCoefficients()[i],
|
||||||
|
@ -293,8 +297,8 @@ void Player::play() {
|
||||||
_injector->setOptions(_options);
|
_injector->setOptions(_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::setCurrentFrame(int currentFrame) {
|
void Player::setCurrentFrame(unsigned int currentFrame) {
|
||||||
if (_recording && (currentFrame < 0 || currentFrame >= _recording->getFrameNumber())) {
|
if (_recording && currentFrame >= _recording->getFrameNumber()) {
|
||||||
stopPlaying();
|
stopPlaying();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -306,12 +310,12 @@ void Player::setCurrentFrame(int currentFrame) {
|
||||||
_timer.start();
|
_timer.start();
|
||||||
setAudionInjectorPosition();
|
setAudionInjectorPosition();
|
||||||
} else {
|
} else {
|
||||||
_pausedFrame = currentFrame;
|
_pausedFrame = _currentFrame;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::setCurrentTime(qint64 currentTime) {
|
void Player::setCurrentTime(unsigned int currentTime) {
|
||||||
if (currentTime < 0 || currentTime >= _recording->getLength()) {
|
if (currentTime >= _recording->getLength()) {
|
||||||
stopPlaying();
|
stopPlaying();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -355,6 +359,18 @@ void Player::setCurrentTime(qint64 currentTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::setVolume(float volume) {
|
||||||
|
_options.setVolume(volume);
|
||||||
|
if (_injector) {
|
||||||
|
_injector->setOptions(_options);
|
||||||
|
}
|
||||||
|
qDebug() << "New volume: " << volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::setAudioOffset(int audioOffset) {
|
||||||
|
_audioOffset = audioOffset;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::setAudionInjectorPosition() {
|
void Player::setAudionInjectorPosition() {
|
||||||
int MSEC_PER_SEC = 1000;
|
int MSEC_PER_SEC = 1000;
|
||||||
int SAMPLE_SIZE = 2; // 16 bits
|
int SAMPLE_SIZE = 2; // 16 bits
|
||||||
|
@ -370,14 +386,19 @@ void Player::setPlayFromCurrentLocation(bool playFromCurrentLocation) {
|
||||||
|
|
||||||
bool Player::computeCurrentFrame() {
|
bool Player::computeCurrentFrame() {
|
||||||
if (!isPlaying()) {
|
if (!isPlaying()) {
|
||||||
_currentFrame = -1;
|
_currentFrame = INVALID_FRAME;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_currentFrame < 0) {
|
if (_currentFrame < 0) {
|
||||||
_currentFrame = 0;
|
_currentFrame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 elapsed = Player::elapsed();
|
quint64 elapsed = glm::clamp(Player::elapsed() - _audioOffset, (qint64)0, (qint64)_recording->getLength());
|
||||||
|
while(_currentFrame >= 0 &&
|
||||||
|
_recording->getFrameTimestamp(_currentFrame) > elapsed) {
|
||||||
|
--_currentFrame;
|
||||||
|
}
|
||||||
|
|
||||||
while (_currentFrame < _recording->getFrameNumber() &&
|
while (_currentFrame < _recording->getFrameNumber() &&
|
||||||
_recording->getFrameTimestamp(_currentFrame) < elapsed) {
|
_recording->getFrameTimestamp(_currentFrame) < elapsed) {
|
||||||
++_currentFrame;
|
++_currentFrame;
|
||||||
|
|
|
@ -44,8 +44,11 @@ public slots:
|
||||||
void loadRecording(RecordingPointer recording);
|
void loadRecording(RecordingPointer recording);
|
||||||
void play();
|
void play();
|
||||||
|
|
||||||
void setCurrentFrame(int currentFrame);
|
void setCurrentFrame(unsigned int currentFrame);
|
||||||
void setCurrentTime(qint64 currentTime);
|
void setCurrentTime(unsigned int currentTime);
|
||||||
|
|
||||||
|
void setVolume(float volume);
|
||||||
|
void setAudioOffset(int audioOffset);
|
||||||
|
|
||||||
void setPlayFromCurrentLocation(bool playFromCurrentPosition);
|
void setPlayFromCurrentLocation(bool playFromCurrentPosition);
|
||||||
void setLoop(bool loop) { _loop = loop; }
|
void setLoop(bool loop) { _loop = loop; }
|
||||||
|
@ -61,19 +64,20 @@ private:
|
||||||
void setAudionInjectorPosition();
|
void setAudionInjectorPosition();
|
||||||
bool computeCurrentFrame();
|
bool computeCurrentFrame();
|
||||||
|
|
||||||
QElapsedTimer _timer;
|
AvatarData* _avatar;
|
||||||
RecordingPointer _recording;
|
RecordingPointer _recording;
|
||||||
int _currentFrame;
|
int _currentFrame;
|
||||||
float _frameInterpolationFactor;
|
float _frameInterpolationFactor;
|
||||||
int _pausedFrame;
|
int _pausedFrame;
|
||||||
qint64 _timerOffset;
|
|
||||||
|
QElapsedTimer _timer;
|
||||||
|
int _timerOffset;
|
||||||
|
int _audioOffset;
|
||||||
|
|
||||||
|
QThread* _audioThread;
|
||||||
QSharedPointer<AudioInjector> _injector;
|
QSharedPointer<AudioInjector> _injector;
|
||||||
AudioInjectorOptions _options;
|
AudioInjectorOptions _options;
|
||||||
|
|
||||||
AvatarData* _avatar;
|
|
||||||
QThread* _audioThread;
|
|
||||||
|
|
||||||
RecordingContext _currentContext;
|
RecordingContext _currentContext;
|
||||||
bool _playFromCurrentPosition;
|
bool _playFromCurrentPosition;
|
||||||
bool _loop;
|
bool _loop;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QtCore/QDataStream>
|
#include <QtCore/QDataStream>
|
||||||
#include <QtCore/QJsonDocument>
|
#include <QtCore/QJsonDocument>
|
||||||
#include <QtCore/QJsonObject>
|
#include <QtCore/QJsonObject>
|
||||||
|
@ -25,9 +27,14 @@
|
||||||
|
|
||||||
const bool VERBOSE_HTTP_REQUEST_DEBUGGING = false;
|
const bool VERBOSE_HTTP_REQUEST_DEBUGGING = false;
|
||||||
|
|
||||||
AccountManager& AccountManager::getInstance() {
|
AccountManager& AccountManager::getInstance(bool forceReset) {
|
||||||
static AccountManager sharedInstance;
|
static std::auto_ptr<AccountManager> sharedInstance(new AccountManager());
|
||||||
return sharedInstance;
|
|
||||||
|
if (forceReset) {
|
||||||
|
sharedInstance.reset(new AccountManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
return *sharedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(OAuthAccessToken)
|
Q_DECLARE_METATYPE(OAuthAccessToken)
|
||||||
|
|
|
@ -42,7 +42,7 @@ const QByteArray ACCESS_TOKEN_AUTHORIZATION_HEADER = "Authorization";
|
||||||
class AccountManager : public QObject {
|
class AccountManager : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static AccountManager& getInstance();
|
static AccountManager& getInstance(bool forceReset = false);
|
||||||
|
|
||||||
void authenticatedRequest(const QString& path,
|
void authenticatedRequest(const QString& path,
|
||||||
QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation,
|
QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation,
|
||||||
|
|
|
@ -35,29 +35,32 @@ const char SOLO_NODE_TYPES[2] = {
|
||||||
|
|
||||||
const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://data.highfidelity.io");
|
const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://data.highfidelity.io");
|
||||||
|
|
||||||
LimitedNodeList* LimitedNodeList::_sharedInstance = NULL;
|
std::auto_ptr<LimitedNodeList> LimitedNodeList::_sharedInstance;
|
||||||
|
|
||||||
LimitedNodeList* LimitedNodeList::createInstance(unsigned short socketListenPort, unsigned short dtlsPort) {
|
LimitedNodeList* LimitedNodeList::createInstance(unsigned short socketListenPort, unsigned short dtlsPort) {
|
||||||
if (!_sharedInstance) {
|
NodeType::init();
|
||||||
NodeType::init();
|
|
||||||
|
if (_sharedInstance.get()) {
|
||||||
|
qDebug() << "LimitedNodeList called with existing instance." <<
|
||||||
|
"Releasing auto_ptr, deleting existing instance and creating a new one.";
|
||||||
|
|
||||||
_sharedInstance = new LimitedNodeList(socketListenPort, dtlsPort);
|
delete _sharedInstance.release();
|
||||||
|
|
||||||
// register the SharedNodePointer meta-type for signals/slots
|
|
||||||
qRegisterMetaType<SharedNodePointer>();
|
|
||||||
} else {
|
|
||||||
qDebug("LimitedNodeList createInstance called with existing instance.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sharedInstance = std::auto_ptr<LimitedNodeList>(new LimitedNodeList(socketListenPort, dtlsPort));
|
||||||
|
|
||||||
|
// register the SharedNodePointer meta-type for signals/slots
|
||||||
|
qRegisterMetaType<SharedNodePointer>();
|
||||||
|
|
||||||
return _sharedInstance;
|
return _sharedInstance.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
LimitedNodeList* LimitedNodeList::getInstance() {
|
LimitedNodeList* LimitedNodeList::getInstance() {
|
||||||
if (!_sharedInstance) {
|
if (!_sharedInstance.get()) {
|
||||||
qDebug("LimitedNodeList getInstance called before call to createInstance. Returning NULL pointer.");
|
qDebug("LimitedNodeList getInstance called before call to createInstance. Returning NULL pointer.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return _sharedInstance;
|
return _sharedInstance.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h> // not on windows, not needed for mac or windows
|
#include <unistd.h> // not on windows, not needed for mac or windows
|
||||||
|
@ -118,7 +119,7 @@ signals:
|
||||||
void nodeKilled(SharedNodePointer);
|
void nodeKilled(SharedNodePointer);
|
||||||
void publicSockAddrChanged(const HifiSockAddr& publicSockAddr);
|
void publicSockAddrChanged(const HifiSockAddr& publicSockAddr);
|
||||||
protected:
|
protected:
|
||||||
static LimitedNodeList* _sharedInstance;
|
static std::auto_ptr<LimitedNodeList> _sharedInstance;
|
||||||
|
|
||||||
LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort);
|
LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort);
|
||||||
LimitedNodeList(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton
|
LimitedNodeList(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton
|
||||||
|
|
|
@ -24,30 +24,31 @@
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
#include "UUID.h"
|
#include "UUID.h"
|
||||||
|
|
||||||
NodeList* NodeList::_sharedInstance = NULL;
|
|
||||||
|
|
||||||
NodeList* NodeList::createInstance(char ownerType, unsigned short socketListenPort, unsigned short dtlsPort) {
|
NodeList* NodeList::createInstance(char ownerType, unsigned short socketListenPort, unsigned short dtlsPort) {
|
||||||
if (!_sharedInstance) {
|
|
||||||
NodeType::init();
|
NodeType::init();
|
||||||
|
|
||||||
|
if (_sharedInstance.get()) {
|
||||||
|
qDebug() << "NodeList called with existing instance." <<
|
||||||
|
"Releasing auto_ptr, deleting existing instance and creating a new one.";
|
||||||
|
|
||||||
_sharedInstance = new NodeList(ownerType, socketListenPort, dtlsPort);
|
delete _sharedInstance.release();
|
||||||
LimitedNodeList::_sharedInstance = _sharedInstance;
|
|
||||||
|
|
||||||
// register the SharedNodePointer meta-type for signals/slots
|
|
||||||
qRegisterMetaType<SharedNodePointer>();
|
|
||||||
} else {
|
|
||||||
qDebug("NodeList createInstance called with existing instance.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _sharedInstance;
|
_sharedInstance = std::auto_ptr<LimitedNodeList>(new NodeList(ownerType, socketListenPort, dtlsPort));
|
||||||
|
|
||||||
|
// register the SharedNodePointer meta-type for signals/slots
|
||||||
|
qRegisterMetaType<SharedNodePointer>();
|
||||||
|
|
||||||
|
return static_cast<NodeList*>(_sharedInstance.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList* NodeList::getInstance() {
|
NodeList* NodeList::getInstance() {
|
||||||
if (!_sharedInstance) {
|
if (!_sharedInstance.get()) {
|
||||||
qDebug("NodeList getInstance called before call to createInstance. Returning NULL pointer.");
|
qDebug("NodeList getInstance called before call to createInstance. Returning NULL pointer.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return _sharedInstance;
|
return static_cast<NodeList*>(_sharedInstance.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned short dtlsListenPort) :
|
NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned short dtlsListenPort) :
|
||||||
|
|
|
@ -84,8 +84,6 @@ public slots:
|
||||||
signals:
|
signals:
|
||||||
void limitOfSilentDomainCheckInsReached();
|
void limitOfSilentDomainCheckInsReached();
|
||||||
private:
|
private:
|
||||||
static NodeList* _sharedInstance;
|
|
||||||
|
|
||||||
NodeList(char ownerType, unsigned short socketListenPort, unsigned short dtlsListenPort);
|
NodeList(char ownerType, unsigned short socketListenPort, unsigned short dtlsListenPort);
|
||||||
NodeList(NodeList const&); // Don't implement, needed to avoid copies of singleton
|
NodeList(NodeList const&); // Don't implement, needed to avoid copies of singleton
|
||||||
void operator=(NodeList const&); // Don't implement, needed to avoid copies of singleton
|
void operator=(NodeList const&); // Don't implement, needed to avoid copies of singleton
|
||||||
|
|
Loading…
Reference in a new issue