Merge branch 'master' of https://github.com/highfidelity/hifi into align-body-to-head-on-reset

This commit is contained in:
Howard Stearns 2015-10-07 18:35:52 -07:00
commit bd0d1eaef6
242 changed files with 5171 additions and 4278 deletions

View file

@ -262,14 +262,9 @@ void AvatarMixer::broadcastAvatarData() {
AvatarDataSequenceNumber lastSeqToReceiver = nodeData->getLastBroadcastSequenceNumber(otherNode->getUUID());
AvatarDataSequenceNumber lastSeqFromSender = otherNodeData->getLastReceivedSequenceNumber();
if (lastSeqToReceiver > lastSeqFromSender) {
// Did we somehow get out of order packets from the sender?
// We don't expect this to happen - in RELEASE we add this to a trackable stat
// and in DEBUG we crash on the assert
if (lastSeqToReceiver > lastSeqFromSender && lastSeqToReceiver != UINT16_MAX) {
// we got out out of order packets from the sender, track it
otherNodeData->incrementNumOutOfOrderSends();
assert(false);
}
// make sure we haven't already sent this data from this sender to this receiver
@ -485,10 +480,13 @@ void AvatarMixer::sendStatsPacket() {
QJsonObject avatarStats;
const QString NODE_OUTBOUND_KBPS_STAT_KEY = "outbound_kbps";
const QString NODE_INBOUND_KBPS_STAT_KEY = "inbound_kbps";
// add the key to ask the domain-server for a username replacement, if it has it
avatarStats[USERNAME_UUID_REPLACEMENT_STATS_KEY] = uuidStringWithoutCurlyBraces(node->getUUID());
avatarStats[NODE_OUTBOUND_KBPS_STAT_KEY] = node->getOutboundBandwidth();
avatarStats[NODE_INBOUND_KBPS_STAT_KEY] = node->getInboundBandwidth();
AvatarMixerClientData* clientData = static_cast<AvatarMixerClientData*>(node->getLinkedData());
if (clientData) {

View file

@ -40,11 +40,14 @@ uint16_t AvatarMixerClientData::getLastBroadcastSequenceNumber(const QUuid& node
void AvatarMixerClientData::loadJSONStats(QJsonObject& jsonObject) const {
jsonObject["display_name"] = _avatar.getDisplayName();
jsonObject["full_rate_distance"] = _fullRateDistance;
jsonObject["max_avatar_distance"] = _maxAvatarDistance;
jsonObject["num_avatars_sent_last_frame"] = _numAvatarsSentLastFrame;
jsonObject["avg_other_avatar_starves_per_second"] = getAvgNumOtherAvatarStarvesPerSecond();
jsonObject["avg_other_avatar_skips_per_second"] = getAvgNumOtherAvatarSkipsPerSecond();
jsonObject["max_av_distance"] = _maxAvatarDistance;
jsonObject["num_avs_sent_last_frame"] = _numAvatarsSentLastFrame;
jsonObject["avg_other_av_starves_per_second"] = getAvgNumOtherAvatarStarvesPerSecond();
jsonObject["avg_other_av_skips_per_second"] = getAvgNumOtherAvatarSkipsPerSecond();
jsonObject["total_num_out_of_order_sends"] = _numOutOfOrderSends;
jsonObject[OUTBOUND_AVATAR_DATA_STATS_KEY] = getOutboundAvatarDataKbps();
jsonObject[INBOUND_AVATAR_DATA_STATS_KEY] = _avatar.getAverageBytesReceivedPerSecond() / (float) BYTES_PER_KILOBIT;
jsonObject["av_data_receive_rate"] = _avatar.getReceiveRate();
}

View file

@ -27,6 +27,7 @@
#include <UUIDHasher.h>
const QString OUTBOUND_AVATAR_DATA_STATS_KEY = "outbound_av_data_kbps";
const QString INBOUND_AVATAR_DATA_STATS_KEY = "inbound_av_data_kbps";
class AvatarMixerClientData : public NodeData {
Q_OBJECT

View file

@ -61,17 +61,17 @@ void ScriptableAvatar::update(float deltatime) {
_jointData.resize(modelJoints.size());
}
float frameIndex = _animationDetails.frameIndex + deltatime * _animationDetails.fps;
if (_animationDetails.loop || frameIndex < _animationDetails.lastFrame) {
while (frameIndex >= _animationDetails.lastFrame) {
frameIndex -= (_animationDetails.lastFrame - _animationDetails.firstFrame);
float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps;
if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) {
while (currentFrame >= _animationDetails.lastFrame) {
currentFrame -= (_animationDetails.lastFrame - _animationDetails.firstFrame);
}
_animationDetails.frameIndex = frameIndex;
_animationDetails.currentFrame = currentFrame;
const int frameCount = _animation->getFrames().size();
const FBXAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(frameIndex) % frameCount);
const FBXAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(frameIndex) % frameCount);
const float frameFraction = glm::fract(frameIndex);
const FBXAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(currentFrame) % frameCount);
const FBXAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(currentFrame) % frameCount);
const float frameFraction = glm::fract(currentFrame);
for (int i = 0; i < modelJoints.size(); i++) {
int mapping = animationJoints.indexOf(modelJoints[i]);

View file

@ -19,7 +19,7 @@ Agent.isAvatar = true;
var jointMapping;
var frameIndex = 0.0;
var currentFrame = 0.0;
var FRAME_RATE = 30.0; // frames per second
@ -35,9 +35,9 @@ Script.update.connect(function(deltaTime) {
jointMapping[i] = animationJointNames.indexOf(avatarJointNames[i]);
}
}
frameIndex += deltaTime * FRAME_RATE;
currentFrame += deltaTime * FRAME_RATE;
var frames = animation.frames;
var rotations = frames[Math.floor(frameIndex) % frames.length].rotations;
var rotations = frames[Math.floor(currentFrame) % frames.length].rotations;
for (var j = 0; j < jointMapping.length; j++) {
var rotationIndex = jointMapping[j];
if (rotationIndex != -1) {

View file

@ -32,8 +32,7 @@
this.leaveEntity = function(entityID) {
Entities.editEntity(entityID, {
animationURL: animationURL,
animationSettings: '{ "frameIndex": 1, "running": false }'
animation: { url: animationURL, currentFrame: 1, running: false }
});
playSound();
@ -41,8 +40,7 @@
this.hoverEnterEntity = function(entityID) {
Entities.editEntity(entityID, {
animationURL: animationURL,
animationSettings: '{ "fps": 24, "firstFrame": 1, "lastFrame": 25, "frameIndex": 1, "running": true, "hold": true }'
animation: { url: animationURL, fps: 24, firstFrame: 1, lastFrame: 25, currentFrame: 1, running: true, hold: true }
});
};
})

View file

@ -18,7 +18,7 @@ function displayAnimationDetails(deltaTime) {
print("count =" + count + " deltaTime=" + deltaTime);
count++;
var animationDetails = MyAvatar.getAnimationDetailsByRole("idle");
print("animationDetails.frameIndex=" + animationDetails.frameIndex);
print("animationDetails.currentFrame=" + animationDetails.currentFrame);
}
function scriptEnding() {

View file

@ -18,7 +18,7 @@ var stopAfter = moveUntil + 100;
var pitch = 0.0;
var yaw = 0.0;
var roll = 0.0;
var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll)
var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll);
var originalProperties = {
type: "Model",
@ -37,8 +37,14 @@ var originalProperties = {
modelURL: "http://public.highfidelity.io/cozza13/club/dragon/dragon.fbx",
rotation: rotation,
animationURL: "http://public.highfidelity.io/cozza13/club/dragon/flying.fbx",
animationIsPlaying: true,
animation: {
url: "http://public.highfidelity.io/cozza13/club/dragon/flying.fbx",
running: true,
fps: 30,
firstFrame: 10,
lastFrame: 20,
loop: true
}
};
var modelID = Entities.addEntity(originalProperties);
@ -99,13 +105,15 @@ function moveModel(deltaTime) {
if (somethingChanged) {
var newProperties = {
animationIsPlaying: isPlaying,
animationFPS: animationFPS,
animation: {
running: isPlaying,
fps: animationFPS
}
};
if (resetFrame) {
print("resetting the frame!");
newProperties.animationFrameIndex = 0;
newProperties.animation.currentFrame = 0;
resetFrame = false;
}

View file

@ -85,8 +85,17 @@ function addButterfly() {
damping: 0.00001,
dimensions: dimensions,
color: color,
animationURL: "http://public.highfidelity.io/models/content/butterfly/butterfly.fbx",
animationSettings: "{\"firstFrame\":0,\"fps\":" + newFrameRate + ",\"frameIndex\":0,\"hold\":false,\"lastFrame\":10000,\"loop\":true,\"running\":true,\"startAutomatically\":false}",
animation: {
url: "http://public.highfidelity.io/models/content/butterfly/butterfly.fbx",
firstFrame: 0,
fps: newFrameRate,
currentFrame: 0,
hold: false,
lastFrame: 10000,
loop: true,
running: true,
startAutomatically:false
},
modelURL: "http://public.highfidelity.io/models/content/butterfly/butterfly.fbx"
};
butterflies.push(Entities.addEntity(properties));

View file

@ -28,7 +28,7 @@
FAST_EMIT_SPEED = 1.0,
GRAVITY_EMIT_ACCELERATON = { x: 0.0, y: -0.3, z: 0.0 },
ZERO_EMIT_ACCELERATON = { x: 0.0, y: 0.0, z: 0.0 },
PI = 3.141593,
PI = 3.141592,
DEG_TO_RAD = PI / 180.0,
NUM_PARTICLE_EXAMPLES = 18;
@ -43,7 +43,7 @@
speedSpread: 0.0,
accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 },
radiusSpread: 0.0,
animationIsPlaying: true
isEmitting: true
});
break;
case 1:
@ -195,7 +195,7 @@
polarFinish: 0.0,
azimuthStart: -PI,
azimuthFinish: PI,
animationIsPlaying: false
isEmitting: false
});
Entities.editEntity(box, {
visible: true
@ -210,15 +210,7 @@
function setUp() {
var boxPoint,
spawnPoint,
animation = {
fps: 30,
frameIndex: 0,
running: true,
firstFrame: 0,
lastFrame: 30,
loop: true
};
spawnPoint;
boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation())));
boxPoint = Vec3.sum(boxPoint, { x: 0.0, y: -0.5, z: 0.0 });
@ -265,8 +257,7 @@
lifespan: 5.0,
visible: false,
locked: false,
animationSettings: animation,
animationIsPlaying: false,
isEmitting: false,
lifetime: 3600 // 1 hour; just in case
});

View file

@ -0,0 +1,42 @@
//
// Created by Bradley Austin Davis on 2015/10/04
// Copyright 2013-2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
IPDScalingTest = function() {
// Switch every 5 seconds between normal IPD and 0 IPD (in seconds)
this.UPDATE_INTERVAL = 10.0;
this.lastUpdateInterval = 0;
this.scaled = false;
var that = this;
Script.scriptEnding.connect(function() {
that.onCleanup();
});
Script.update.connect(function(deltaTime) {
that.lastUpdateInterval += deltaTime;
if (that.lastUpdateInterval >= that.UPDATE_INTERVAL) {
that.onUpdate(that.lastUpdateInterval);
that.lastUpdateInterval = 0;
}
});
}
IPDScalingTest.prototype.onCleanup = function() {
HMD.setIPDScale(1.0);
}
IPDScalingTest.prototype.onUpdate = function(deltaTime) {
this.scaled = !this.scaled;
if (this.scaled) {
HMD.ipdScale = 0.0;
} else {
HMD.ipdScale = 1.0;
}
}
new IPDScalingTest();

View file

@ -0,0 +1,103 @@
Script.include("../../libraries/utils.js");
PickerTest = function() {
// Switch every 5 seconds between normal IPD and 0 IPD (in seconds)
this.UPDATE_INTERVAL = 10.0;
this.lastUpdateInterval = 0;
this.ballId = Overlays.addOverlay("sphere", {
position: { x: 0, y: 0, z: 0 },
color: { red: 0, green: 255, blue: 0 },
size: 0.1,
solid: true,
alpha: 1.0,
visible: true,
});
this.ballId2 = Overlays.addOverlay("sphere", {
position: { x: 0, y: 0, z: 0 },
color: { red: 255, green: 0, blue: 0 },
size: 0.05,
solid: true,
alpha: 1.0,
visible: true,
});
var that = this;
Script.scriptEnding.connect(function() {
that.onCleanup();
});
Script.update.connect(function(deltaTime) {
that.lastUpdateInterval += deltaTime;
if (that.lastUpdateInterval >= that.UPDATE_INTERVAL) {
that.onUpdate(that.lastUpdateInterval);
that.lastUpdateInterval = 0;
}
});
Controller.mousePressEvent.connect(function(event) {
that.onMousePress(event);
});
Controller.mouseMoveEvent.connect(function(event) {
that.onMouseMove(event);
});
Controller.mouseReleaseEvent.connect(function(event) {
that.onMouseRelease(event);
});
};
PickerTest.prototype.onCleanup = function() {
Overlays.deleteOverlay(this.ballId)
Overlays.deleteOverlay(this.ballId2)
}
PickerTest.prototype.updateOverlays = function() {
var pickRay = Camera.computePickRay(this.x, this.y);
var origin = pickRay.origin;
var direction = pickRay.direction;
var position = Vec3.sum(origin, direction)
Overlays.editOverlay(this.ballId, {
position: position
});
Overlays.editOverlay(this.ballId2, {
position: origin
});
}
PickerTest.prototype.onUpdate = function(deltaTime) {
if (this.clicked) {
this.updateOverlays();
}
}
PickerTest.prototype.onMousePress = function(event) {
if (event.button !== "LEFT") {
return
}
this.clicked = true;
this.x = event.x;
this.y = event.y;
this.updateOverlays();
}
PickerTest.prototype.onMouseRelease = function(event) {
if (event.button !== "LEFT") {
return
}
this.clicked = false;
}
PickerTest.prototype.onMouseMove = function(event) {
if (this.clicked) {
this.x = event.x;
this.y = event.y;
this.updateOverlays();
}
}
var PickerTest = new PickerTest();

View file

@ -117,15 +117,6 @@ Rocket = function(point, colorPalette) {
}
});
this.animationSettings = JSON.stringify({
fps: 40,
frameIndex: 0,
running: true,
firstFrame: 0,
lastFrame: 20,
loop: false
});
this.direction = {
x: randFloat(-0.4, 0.4),
y: 1.0,
@ -170,7 +161,7 @@ Rocket.prototype.explode = function(position) {
print(JSON.stringify(color));
this.bursts.push(Entities.addEntity({
type: "ParticleEffect",
animationSettings: this.animationSettings,
isEmitting: true,
position: position,
textures: 'https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png',
emitRate: this.emitRate,

View file

@ -10,6 +10,15 @@
var DEGREES_TO_RADIANS = PI / 180.0;
var RADIANS_TO_DEGREES = 180.0 / PI;
debugPrint = function(message) {
EventBridge.emitWebEvent(
JSON.stringify({
type:"print",
message: message
})
);
};
function enableChildren(el, selector) {
els = el.querySelectorAll(selector);
for (var i = 0; i < els.length; i++) {
@ -37,7 +46,7 @@
};
}
function createEmitGroupCheckedPropertyUpdateFunction(group, propertyName) {
return function() {
return function () {
var properties = {};
properties[group] = {};
properties[group][propertyName] = this.checked;
@ -282,7 +291,11 @@
var elModelAnimationPlaying = document.getElementById("property-model-animation-playing");
var elModelAnimationFPS = document.getElementById("property-model-animation-fps");
var elModelAnimationFrame = document.getElementById("property-model-animation-frame");
var elModelAnimationSettings = document.getElementById("property-model-animation-settings");
var elModelAnimationFirstFrame = document.getElementById("property-model-animation-first-frame");
var elModelAnimationLastFrame = document.getElementById("property-model-animation-last-frame");
var elModelAnimationLoop = document.getElementById("property-model-animation-loop");
var elModelAnimationHold = document.getElementById("property-model-animation-hold");
var elModelAnimationStartAutomatically = document.getElementById("property-model-animation-start-automatically");
var elModelTextures = document.getElementById("property-model-textures");
var elModelOriginalTextures = document.getElementById("property-model-original-textures");
@ -506,11 +519,15 @@
elModelURL.value = properties.modelURL;
elShapeType.value = properties.shapeType;
elCompoundShapeURL.value = properties.compoundShapeURL;
elModelAnimationURL.value = properties.animationURL;
elModelAnimationPlaying.checked = properties.animationIsPlaying;
elModelAnimationFPS.value = properties.animationFPS;
elModelAnimationFrame.value = properties.animationFrameIndex;
elModelAnimationSettings.value = properties.animationSettings;
elModelAnimationURL.value = properties.animation.url;
elModelAnimationPlaying.checked = properties.animation.running;
elModelAnimationFPS.value = properties.animation.fps;
elModelAnimationFrame.value = properties.animation.currentFrame;
elModelAnimationFirstFrame.value = properties.animation.firstFrame;
elModelAnimationLastFrame.value = properties.animation.lastFrame;
elModelAnimationLoop.checked = properties.animation.loop;
elModelAnimationHold.checked = properties.animation.hold;
elModelAnimationStartAutomatically.checked = properties.animation.startAutomatically;
elModelTextures.value = properties.textures;
elModelOriginalTextures.value = properties.originalTextures;
} else if (properties.type == "Web") {
@ -756,11 +773,17 @@
elModelURL.addEventListener('change', createEmitTextPropertyUpdateFunction('modelURL'));
elShapeType.addEventListener('change', createEmitTextPropertyUpdateFunction('shapeType'));
elCompoundShapeURL.addEventListener('change', createEmitTextPropertyUpdateFunction('compoundShapeURL'));
elModelAnimationURL.addEventListener('change', createEmitTextPropertyUpdateFunction('animationURL'));
elModelAnimationPlaying.addEventListener('change', createEmitCheckedPropertyUpdateFunction('animationIsPlaying'));
elModelAnimationFPS.addEventListener('change', createEmitNumberPropertyUpdateFunction('animationFPS'));
elModelAnimationFrame.addEventListener('change', createEmitNumberPropertyUpdateFunction('animationFrameIndex'));
elModelAnimationSettings.addEventListener('change', createEmitTextPropertyUpdateFunction('animationSettings'));
elModelAnimationURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('animation', 'url'));
elModelAnimationPlaying.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation','running'));
elModelAnimationFPS.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation','fps'));
elModelAnimationFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'currentFrame'));
elModelAnimationFirstFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'firstFrame'));
elModelAnimationLastFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'lastFrame'));
elModelAnimationLoop.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'loop'));
elModelAnimationHold.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'hold'));
elModelAnimationStartAutomatically.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'startAutomatically'));
elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures'));
elTextText.addEventListener('change', createEmitTextPropertyUpdateFunction('text'));
@ -1280,11 +1303,35 @@
</div>
</div>
<div class="model-section property">
<div class="label">Animation Settings</div>
<div class="label">Animation First Frame</div>
<div class="value">
<textarea id="property-model-animation-settings"></textarea>
<input class="coord" type='number' id="property-model-animation-first-frame">
</div>
</div>
<div class="model-section property">
<div class="label">Animation Last Frame</div>
<div class="value">
<input class="coord" type='number' id="property-model-animation-last-frame">
</div>
</div>
<div class="model-section property">
<span class="label">Animation Loop</span>
<span class="value">
<input type='checkbox' id="property-model-animation-loop">
</span>
</div>
<div class="model-section property">
<span class="label">Animation Hold</span>
<span class="value">
<input type='checkbox' id="property-model-animation-hold">
</span>
</div>
<div class="model-section property">
<span class="label">Animation Start Automatically</span>
<span class="value">
<input type='checkbox' id="property-model-animation-start-automatically">
</span>
</div>
<div class="model-section property">
<div class="label">Textures</div>
<div class="value">

View file

@ -26,8 +26,7 @@ EntityPropertyDialogBox = (function () {
var rescalePercentage;
var editModelID = -1;
var previousAnimationIsPlaying;
var previousAnimationFrameIndex;
var previousAnimationSettings;
var previousAnimationCurrentFrame;
that.cleanup = function () {
};
@ -56,18 +55,15 @@ EntityPropertyDialogBox = (function () {
index++;
array.push({ label: "Compound Shape URL:", value: properties.compoundShapeURL });
index++;
array.push({ label: "Animation URL:", value: properties.animationURL });
array.push({ label: "Animation URL:", value: properties.animation.url });
index++;
array.push({ label: "Animation is playing:", type: "checkbox", value: properties.animationIsPlaying });
previousAnimationIsPlaying = properties.animationIsPlaying;
array.push({ label: "Animation is playing:", type: "checkbox", value: properties.animation.running });
previousAnimationIsPlaying = properties.animation.running;
index++;
array.push({ label: "Animation FPS:", value: properties.animationFPS });
array.push({ label: "Animation FPS:", value: properties.animation.fps });
index++;
array.push({ label: "Animation Frame:", value: properties.animationFrameIndex });
previousAnimationFrameIndex = properties.animationFrameIndex;
index++;
array.push({ label: "Animation Settings:", value: properties.animationSettings });
previousAnimationSettings = properties.animationSettings;
array.push({ label: "Animation Frame:", value: properties.animation.currentFrame });
previousAnimationCurrentFrame = properties.animation.currentFrame;
index++;
array.push({ label: "Textures:", value: properties.textures });
index++;
@ -312,30 +308,24 @@ EntityPropertyDialogBox = (function () {
properties.modelURL = array[index++].value;
properties.shapeType = array[index++].value;
properties.compoundShapeURL = array[index++].value;
properties.animationURL = array[index++].value;
properties.animation.url = array[index++].value;
var newAnimationIsPlaying = array[index++].value;
if (previousAnimationIsPlaying != newAnimationIsPlaying) {
properties.animationIsPlaying = newAnimationIsPlaying;
properties.animation.running = newAnimationIsPlaying;
} else {
delete properties.animationIsPlaying;
delete properties.animation.running;
}
properties.animationFPS = array[index++].value;
properties.animation.fps = array[index++].value;
var newAnimationFrameIndex = array[index++].value;
if (previousAnimationFrameIndex != newAnimationFrameIndex) {
properties.animationFrameIndex = newAnimationFrameIndex;
var newAnimationCurrentFrame = array[index++].value;
if (previousAnimationCurrentFrame != newAnimationCurrentFrame) {
properties.animation.currentFrame = newAnimationCurrentFrame;
} else {
delete properties.animationFrameIndex;
delete properties.animation.currentFrame;
}
var newAnimationSettings = array[index++].value;
if (previousAnimationSettings != newAnimationSettings) {
properties.animationSettings = newAnimationSettings;
} else {
delete properties.animationSettings;
}
properties.textures = array[index++].value;
index++; // skip textureNames label
}

View file

@ -342,7 +342,6 @@ Keyboard = (function(params) {
if (HMD.magnifier == visible) {
HMD.toggleMagnifier();
}
Window.cursorVisible = !visible;
Overlays.editOverlay(tthis.background, { visible: tthis.visible });
for (var i = 0; i < this.keys.length; i++) {
this.keys[i].updateVisibility();

View file

@ -51,15 +51,6 @@
this.emitRate = randInt(80, 120);
this.emitStrength = randInt(4.0, 6.0);
this.animationSettings = JSON.stringify({
fps: 10,
frameIndex: 0,
running: true,
firstFrame: 0,
lastFrame: 50,
loop: true
});
this.direction = {
x: randFloat(-0.3, 0.3),
y: 1.0,
@ -85,7 +76,7 @@
var color = colorPalette[colorIndex];
this.emitters.push(Entities.addEntity({
type: "ParticleEffect",
animationSettings: this.animationSettings,
isEmitting: true,
position: this.point,
textures: TEXTURE_PATH,
emitRate: this.emitRate,

View file

@ -72,10 +72,7 @@ var keysToIgnore = [
'marketplaceID',
'collisionSoundURL',
'shapeType',
'animationSettings',
'animationFrameIndex',
'animationIsPlaying',
'animationFPS',
'isEmitting',
'sittingPoints',
'originalTextures'
];

View file

@ -55,15 +55,7 @@ var particleProperties;
function setUp() {
var boxPoint,
spawnPoint,
animation = {
fps: 30,
frameIndex: 0,
running: true,
firstFrame: 0,
lastFrame: 30,
loop: true
};
spawnPoint;
boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation())));
boxPoint = Vec3.sum(boxPoint, {
@ -138,8 +130,7 @@ function setUp() {
lifespan: 5.0,
visible: false,
locked: false,
animationSettings: animation,
animationIsPlaying: true,
isEmitting: true,
lifetime: 3600 // 1 hour; just in case
});

View file

@ -11,7 +11,7 @@
gravity: { x: 0, y: 0, z: 0 },
visible: true,
locked: false,
lifetime: 6000 });
lifetime: 6000});
var self = this;
this.timer = Script.setInterval(function () {
var colorProp = { color: { red: Math.random() * 255,
@ -29,20 +29,15 @@
// constructor
function TestFx(color, emitDirection, emitRate, emitStrength, blinkRate) {
var animationSettings = JSON.stringify({ fps: 30,
frameIndex: 0,
running: true,
firstFrame: 0,
lastFrame: 30,
loop: true });
var PI = 3.141593;
var DEG_TO_RAD = PI / 180.0;
this.entity = Entities.addEntity({ type: "ParticleEffect",
animationSettings: animationSettings,
isEmitting: true,
position: spawnPoint,
dimensions: {x: 2, y: 2, z: 2},
emitSpeed: 5,
emitSpeed: 0.05,
maxParticles: 2,
speedSpread: 2,
polarFinish: 30 * DEG_TO_RAD,
emitAcceleration: {x: 0, y: -9.8, z: 0},
@ -58,8 +53,8 @@
this.timer = Script.setInterval(function () {
// flip is playing state
self.isPlaying = !self.isPlaying;
var animProp = { animationIsPlaying: self.isPlaying };
Entities.editEntity(self.entity, animProp);
var emittingProp = { isEmitting: self.isPlaying };
Entities.editEntity(self.entity, emittingProp);
}, (1 / blinkRate) * 1000);
}

View file

@ -1,12 +1,10 @@
//
// createHoop.js
// examples/entityScripts
//
// Created by James B. Pollack on 9/29/2015
// Copyright 2015 High Fidelity, Inc.
//
// This is a script that creates a persistent basketball hoop with a working collision hull. Feel free to move it.
// Run basketball.js to make a basketball.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html

View file

@ -0,0 +1,152 @@
//
// createRack.js
//
// Created by James B. Pollack @imgntn on 10/5/2015
// Copyright 2015 High Fidelity, Inc.
//
// This is a script that creates a persistent basketball rack.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */
Script.include("../../libraries/utils.js");
var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx";
var collisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav";
var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx";
var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/rack_collision_hull.obj";
var NUMBER_OF_BALLS = 4;
var DIAMETER = 0.30;
var RESET_DISTANCE = 1;
var MINIMUM_MOVE_LENGTH = 0.05;
var GRABBABLE_DATA_KEY = "grabbableKey";
var rackStartPosition =
Vec3.sum(MyAvatar.position,
Vec3.multiplyQbyV(MyAvatar.orientation, {
x: 0,
y: 0.0,
z: -2
}));
var rack = Entities.addEntity({
name: 'Basketball Rack',
type: "Model",
modelURL: rackURL,
position: rackStartPosition,
shapeType: 'compound',
gravity: {
x: 0,
y: -9.8,
z: 0
},
linearDamping: 1,
dimensions: {
x: 0.4,
y: 1.37,
z: 1.73
},
collisionsWillMove: true,
ignoreForCollisions: false,
collisionSoundURL: collisionSoundURL,
compoundShapeURL: rackCollisionHullURL,
// scriptURL: rackScriptURL
});
setEntityCustomData(GRABBABLE_DATA_KEY, rack, {
grabbable: false
});
var nonCollidingBalls = [];
var collidingBalls = [];
var originalBallPositions = [];
function createCollidingBalls() {
var position = rackStartPosition;
var i;
for (i = 0; i < NUMBER_OF_BALLS; i++) {
var ballPosition = {
x: position.x,
y: position.y + DIAMETER * 2,
z: position.z + (DIAMETER) - (DIAMETER * i)
};
var collidingBall = Entities.addEntity({
type: "Model",
name: 'Colliding Basketball',
shapeType: 'Sphere',
position: ballPosition,
dimensions: {
x: DIAMETER,
y: DIAMETER,
z: DIAMETER
},
restitution: 1.0,
linearDamping: 0.00001,
gravity: {
x: 0,
y: -9.8,
z: 0
},
collisionsWillMove: true,
ignoreForCollisions: false,
modelURL: basketballURL,
});
collidingBalls.push(collidingBall);
originalBallPositions.push(position);
}
}
function testBallDistanceFromStart() {
var resetCount = 0;
collidingBalls.forEach(function(ball, index) {
var currentPosition = Entities.getEntityProperties(ball, "position").position;
var originalPosition = originalBallPositions[index];
var distance = Vec3.subtract(originalPosition, currentPosition);
var length = Vec3.length(distance);
if (length > RESET_DISTANCE) {
Script.setTimeout(function() {
var newPosition = Entities.getEntityProperties(ball, "position").position;
var moving = Vec3.length(Vec3.subtract(currentPosition, newPosition));
if (moving < MINIMUM_MOVE_LENGTH) {
resetCount++;
if (resetCount === NUMBER_OF_BALLS) {
deleteCollidingBalls();
createCollidingBalls();
}
}
}, 200)
}
});
}
function deleteEntity(entityID) {
if (entityID === rack) {
deleteCollidingBalls();
Script.clearInterval(distanceCheckInterval);
Entities.deletingEntity.disconnect(deleteEntity);
}
}
function deleteCollidingBalls() {
while (collidingBalls.length > 0) {
Entities.deleteEntity(collidingBalls.pop());
}
}
createCollidingBalls();
Entities.deletingEntity.connect(deleteEntity);
var distanceCheckInterval = Script.setInterval(testBallDistanceFromStart, 1000);
function atEnd() {
Script.clearInterval(distanceCheckInterval);
}
Script.scriptEnding.connect(atEnd);

View file

@ -1,5 +1,5 @@
//
// basketball.js
// createSingleBasketball.js
// examples
//
// Created by Philip Rosedale on August 20, 2015
@ -17,34 +17,39 @@ var collisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav";
var basketball = null;
var originalPosition = null;
var hasMoved = false;
var hasMoved = false;
var GRAVITY = -9.8;
var DISTANCE_IN_FRONT_OF_ME = 1.0;
var START_MOVE = 0.01;
var DIAMETER = 0.30;
var DIAMETER = 0.30;
function makeBasketball() {
function makeBasketball() {
var position = Vec3.sum(MyAvatar.position,
Vec3.multiplyQbyV(MyAvatar.orientation,
{ x: 0, y: 0.0, z: -DISTANCE_IN_FRONT_OF_ME }));
Vec3.multiplyQbyV(MyAvatar.orientation, {
x: 0,
y: 0.0,
z: -DISTANCE_IN_FRONT_OF_ME
}));
var rotation = Quat.multiply(MyAvatar.orientation,
Quat.fromPitchYawRollDegrees(0, -90, 0));
Quat.fromPitchYawRollDegrees(0, -90, 0));
basketball = Entities.addEntity({
type: "Model",
position: position,
rotation: rotation,
dimensions: { x: DIAMETER,
y: DIAMETER,
z: DIAMETER },
collisionsWillMove: true,
collisionSoundURL: collisionSoundURL,
modelURL: basketballURL,
restitution: 1.0,
linearDamping: 0.00001,
shapeType: "sphere"
});
originalPosition = position;
type: "Model",
position: position,
rotation: rotation,
dimensions: {
x: DIAMETER,
y: DIAMETER,
z: DIAMETER
},
collisionsWillMove: true,
collisionSoundURL: collisionSoundURL,
modelURL: basketballURL,
restitution: 1.0,
linearDamping: 0.00001,
shapeType: "sphere"
});
originalPosition = position;
}
function update() {
@ -55,28 +60,33 @@ function update() {
var moved = Vec3.length(Vec3.subtract(originalPosition, newProperties.position));
if (!hasMoved && (moved > START_MOVE)) {
hasMoved = true;
Entities.editEntity(basketball, { gravity: {x: 0, y: GRAVITY, z: 0 }});
Entities.editEntity(basketball, {
gravity: {
x: 0,
y: GRAVITY,
z: 0
}
});
}
var MAX_DISTANCE = 10.0;
var distance = Vec3.length(Vec3.subtract(MyAvatar.position, newProperties.position));
if (distance > MAX_DISTANCE) {
deleteStuff();
}
}
}
}
function scriptEnding() {
deleteStuff();
}
function deleteStuff() {
function deleteStuff() {
if (basketball != null) {
Entities.deleteEntity(basketball);
basketball = null;
hasMoved = false;
hasMoved = false;
}
}
Script.update.connect(update);
Script.scriptEnding.connect(scriptEnding);
Script.scriptEnding.connect(scriptEnding);

View file

@ -0,0 +1,141 @@
//
// createTestBlocks.js
//
// Script Type: Entity Spawner
// Created by James B. Pollack on 10/5/2015
// Copyright 2015 High Fidelity, Inc.
//
//
// This script creates a 'stonehenge' formation of physical blocks for testing knock over properties.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */
var BLOCK_GRAVITY = {
x: 0,
y: -9.8,
z: 0
};
var LINEAR_DAMPING = 0.2;
var RED = {
red: 255,
green: 0,
blue: 0
};
var GREEN = {
red: 0,
green: 255,
blue: 0
};
var BLUE = {
red: 0,
green: 0,
blue: 255
};
var blockDimensions = {
x: 0.12,
y: 0.25,
z: 0.50
};
var centerPosition = {
x: 0,
y: 0,
z: 0
};
var DISTANCE_IN_FRONT_OF_ME = 2.0;
var position = Vec3.sum(MyAvatar.position,
Vec3.multiplyQbyV(MyAvatar.orientation, {
x: 0,
y: 0.0,
z: -DISTANCE_IN_FRONT_OF_ME
}));
var sideBlock1_position = {
x: position.x,
y: position.y,
z: position.z - 0.25
};
var sideBlock2_position = {
x: position.x,
y: position.y,
z: position.z + 0.25
};
var topBlock_position = {
x: position.x,
y: position.y + 0.31,
z: position.z
};
var sideBlock1_rotation = Quat.fromPitchYawRollDegrees(90, 90, 0);
var sideBlock2_rotation = Quat.fromPitchYawRollDegrees(90, 90, 0);
var topBlock_rotation = Quat.fromPitchYawRollDegrees(0, 0, 90);
var topBlock = Entities.addEntity({
name: 'Top Block',
color: BLUE,
type: 'Box',
shapeType: 'box',
dimensions: blockDimensions,
position: topBlock_position,
rotation: topBlock_rotation,
linearDamping: LINEAR_DAMPING,
gravity: BLOCK_GRAVITY,
collisionsWillMove: true,
velocity: {
x: 0,
y: -0.01,
z: 0
}
});
var sideBlock1 = Entities.addEntity({
name: 'Top Block',
color: GREEN,
type: 'Box',
shapeType: 'box',
dimensions: blockDimensions,
position: sideBlock1_position,
rotation: sideBlock1_rotation,
linearDamping: LINEAR_DAMPING,
gravity: BLOCK_GRAVITY,
collisionsWillMove: true
});
var sideBlock2 = Entities.addEntity({
name: 'Side Block',
color: GREEN,
type: 'Box',
shapeType: 'box',
dimensions: blockDimensions,
position: sideBlock2_position,
rotation: sideBlock2_rotation,
collsionsWillMove: true,
linearDamping: LINEAR_DAMPING,
gravity: BLOCK_GRAVITY,
collisionsWillMove: true
});
var ground = Entities.addEntity({
type: 'Box',
dimensions: {
x: 2,
y: 0.02,
z: 1
},
color: RED,
position: {
x: position.x,
y: position.y - 0.25,
z: position.z
}
});

View file

@ -384,13 +384,14 @@ function createOverlays() {
}
var TEMPORARY_LIFETIME = 60;
var ANIMATION_SETTINGS = JSON.stringify({
var ANIMATION_SETTINGS = {
url: "http://s3.amazonaws.com/hifi-public/animations/Breakdancing/breakdance_ready.fbx",
fps: 30,
running: true,
loop: true,
firstFrame: 1,
lastFrame: 10000
});
};
var NATURAL_DIMENSIONS = { x: 1.63, y: 1.67, z: 0.31 };
var DIMENSIONS = Vec3.multiply(NATURAL_DIMENSIONS, 0.3);
@ -407,8 +408,7 @@ function createPuppet(model, location) {
type: "Model",
modelURL: model,
registrationPoint: { x: 0.5, y: 0, z: 0.5 },
animationURL: "http://s3.amazonaws.com/hifi-public/animations/Breakdancing/breakdance_ready.fbx",
animationSettings: ANIMATION_SETTINGS,
animation: ANIMATION_SETTINGS,
position: location,
ignoreForCollisions: true,
dimensions: DIMENSIONS,
@ -558,7 +558,7 @@ breakdanceUpdate = function(deltaTime) {
var props = Entities.getEntityProperties(puppetEntityID);
//print("puppetEntityID:" + puppetEntityID + "age:"+props.age);
Entities.editEntity(puppetEntityID, {
animationURL: poses[poseValue].animation,
animation: { url: poses[poseValue].animation },
lifetime: TEMPORARY_LIFETIME + props.age // renew lifetime
});
}

View file

@ -35,8 +35,10 @@
startNearGrab: function() {
Entities.editEntity(this.entityID, {
animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx",
animationFrameIndex: 0
animation: {
url: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx",
currentFrame: 0
}
});
Entities.editEntity(_this.entityID, {
@ -65,11 +67,10 @@
if (this.isGrabbed === true && this.hand === this.initialHand) {
this.audioInjector.stop();
Entities.editEntity(this.entityID, {
animationFrameIndex: 0
});
Entities.editEntity(this.entityID, {
animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"
animation: {
url: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx",
currentFrame: 0
}
});
this.isGrabbed = false;

View file

@ -33,15 +33,6 @@ var originalPosition = null;
var isGrenade = false;
var isBurning = false;
var animationSettings = JSON.stringify({
running: true,
loop: true
});
var explodeAnimationSettings = JSON.stringify({
running: true,
loop: false
});
var GRAVITY = -9.8;
var TIME_TO_EXPLODE = 2500;
var DISTANCE_IN_FRONT_OF_ME = 1.0;
@ -85,7 +76,7 @@ function update() {
// Create fuse particles
particles = Entities.addEntity({
type: "ParticleEffect",
animationSettings: animationSettings,
isEmitting: true,
position: newProperties.position,
textures: 'https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png',
emitRate: 100,
@ -142,7 +133,7 @@ function boom() {
Audio.playSound(boomSound, audioOptions);
Entities.addEntity({
type: "ParticleEffect",
animationSettings: explodeAnimationSettings,
isEmitting: true,
position: properties.position,
textures: 'https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png',
emitRate: 200,

View file

@ -0,0 +1,92 @@
//
// lightSwitch.js
// examples/entityScripts
//
// Created by Eric Levin on 10/2/15.
// Copyright 2015 High Fidelity, Inc.
//
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */
//per script
/*global LightSwitch */
(function () {
var _this;
var utilitiesScript = Script.resolvePath("../libraries/utils.js");
Script.include(utilitiesScript);
LightSwitch = function () {
_this = this;
this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav");
};
LightSwitch.prototype = {
clickReleaseOnEntity: function (entityID, mouseEvent) {
if (!mouseEvent.isLeftButton) {
return;
}
this.toggleLights();
},
startNearGrabNonColliding: function () {
this.toggleLights();
},
toggleLights: function () {
var lightData = getEntityCustomData(this.resetKey, this.entityID, {});
var on = !lightData.on;
var lightType = lightData.type;
var lights = Entities.findEntities(this.position, 20);
lights.forEach(function (light) {
var type = getEntityCustomData(_this.resetKey, light, {}).type;
if (type === lightType && JSON.stringify(light) !== JSON.stringify(_this.entityID)) {
Entities.editEntity(light, {
visible: on
});
}
});
this.flipSwitch();
Audio.playSound(this.switchSound, {
volume: 0.5,
position: this.position
});
setEntityCustomData(this.resetKey, this.entityID, {
on: on,
type: lightType,
resetMe: true
});
},
flipSwitch: function () {
var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation;
var axis = {
x: 0,
y: 1,
z: 0
};
var dQ = Quat.angleAxis(180, axis);
rotation = Quat.multiply(rotation, dQ);
Entities.editEntity(this.entityID, {
rotation: rotation
});
},
preload: function (entityID) {
this.entityID = entityID;
this.resetKey = "resetMe";
//The light switch is static, so just cache its position once
this.position = Entities.getEntityProperties(this.entityID, "position").position;
}
};
// entity scripts always need to return a newly constructed object of our type
return new LightSwitch();
});

View file

@ -1,202 +0,0 @@
//
// lightSwitchGarage.js.js
// examples/entityScripts
//
// Created by Eric Levin on 9/21/15.
// Copyright 2015 High Fidelity, Inc.
//
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function() {
var _this;
// this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember
// our this object, so we can access it in cases where we're called without a this (like in the case of various global signals)
LightSwitchGarage = function() {
_this = this;
this.lightStateKey = "lightStateKey";
this.resetKey = "resetMe";
this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav");
};
LightSwitchGarage.prototype = {
clickReleaseOnEntity: function(entityID, mouseEvent) {
if (!mouseEvent.isLeftButton) {
return;
}
this.toggleLights();
},
startNearGrabNonColliding: function() {
this.toggleLights();
},
toggleLights: function() {
var defaultLightData = {
on: false
};
var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData);
if (lightState.on === true) {
this.clearLights();
} else if (lightState.on === false) {
this.createLights();
}
this.flipLights();
Audio.playSound(this.switchSound, {
volume: 0.5,
position: this.position
});
},
clearLights: function() {
var entities = Entities.findEntities(MyAvatar.position, 100);
var self = this;
entities.forEach(function(entity) {
var resetData = getEntityCustomData(self.resetKey, entity, {})
if (resetData.resetMe === true && resetData.lightType === "Sconce Light Garage") {
Entities.deleteEntity(entity);
}
});
setEntityCustomData(this.lightStateKey, this.entityID, {
on: false
});
},
createLights: function() {
var sconceLight3 = Entities.addEntity({
type: "Light",
position: {
x: 545.49468994140625,
y: 496.24026489257812,
z: 500.63516235351562
},
name: "Sconce 3 Light",
dimensions: {
x: 2.545,
y: 2.545,
z: 2.545
},
cutoff: 90,
color: {
red: 217,
green: 146,
blue: 24
}
});
setEntityCustomData(this.resetKey, sconceLight3, {
resetMe: true,
lightType: "Sconce Light Garage"
});
var sconceLight4 = Entities.addEntity({
type: "Light",
position: {
x: 550.90399169921875,
y: 496.24026489257812,
z: 507.90237426757812
},
name: "Sconce 4 Light",
dimensions: {
x: 2.545,
y: 2.545,
z: 2.545
},
cutoff: 90,
color: {
red: 217,
green: 146,
blue: 24
}
});
setEntityCustomData(this.resetKey, sconceLight4, {
resetMe: true,
lightType: "Sconce Light Garage"
});
var sconceLight5 = Entities.addEntity({
type: "Light",
position: {
x: 548.407958984375,
y: 496.24026489257812,
z: 509.5504150390625
},
name: "Sconce 5 Light",
dimensions: {
x: 2.545,
y: 2.545,
z: 2.545
},
cutoff: 90,
color: {
red: 217,
green: 146,
blue: 24
}
});
setEntityCustomData(this.resetKey, sconceLight5, {
resetMe: true,
lightType: "Sconce Light Garage"
});
setEntityCustomData(this.lightStateKey, this.entityID, {
on: true
});
},
flipLights: function() {
// flip model to give illusion of light switch being flicked
var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation;
var axis = {
x: 0,
y: 1,
z: 0
};
var dQ = Quat.angleAxis(180, axis);
rotation = Quat.multiply(rotation, dQ);
Entities.editEntity(this.entityID, {
rotation: rotation
});
},
preload: function(entityID) {
this.entityID = entityID;
//The light switch is static, so just cache its position once
this.position = Entities.getEntityProperties(this.entityID, "position").position;
var defaultLightData = {
on: false
};
var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData);
//If light is off, then we create two new lights- at the position of the sconces
if (lightState.on === false) {
this.createLights();
this.flipLights();
}
//If lights are on, do nothing!
},
};
// entity scripts always need to return a newly constructed object of our type
return new LightSwitchGarage();
})

View file

@ -1,179 +0,0 @@
//
// lightSwitchHall.js
// examples/entityScripts
//
// Created by Eric Levin on 9/21/15.
// Copyright 2015 High Fidelity, Inc.
//
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function() {
var _this;
// this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember
// our this object, so we can access it in cases where we're called without a this (like in the case of various global signals)
LightSwitchHall = function() {
_this = this;
this.lightStateKey = "lightStateKey";
this.resetKey = "resetMe";
this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav");
};
LightSwitchHall.prototype = {
clickReleaseOnEntity: function(entityId, mouseEvent) {
if (!mouseEvent.isLeftButton) {
return;
}
this.toggleLights();
},
startNearGrabNonColliding: function() {
this.toggleLights();
},
toggleLights: function() {
var defaultLightData = {
on: false
};
var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData);
if (lightState.on === true) {
this.clearLights();
} else if (lightState.on === false) {
this.createLights();
}
// flip model to give illusion of light switch being flicked
this.flipLights();
Audio.playSound(this.switchSound, {
volume: 0.5,
position: this.position
});
},
clearLights: function() {
var entities = Entities.findEntities(MyAvatar.position, 100);
var self = this;
entities.forEach(function(entity) {
var resetData = getEntityCustomData(self.resetKey, entity, {})
if (resetData.resetMe === true && resetData.lightType === "Sconce Light Hall") {
Entities.deleteEntity(entity);
}
});
setEntityCustomData(this.lightStateKey, this.entityID, {
on: false
});
},
createLights: function() {
var sconceLight1 = Entities.addEntity({
type: "Light",
position: {
x: 543.75,
y: 496.24,
z: 511.13
},
name: "Sconce 1 Light",
dimensions: {
x: 2.545,
y: 2.545,
z: 2.545
},
cutoff: 90,
color: {
red: 217,
green: 146,
blue: 24
}
});
setEntityCustomData(this.resetKey, sconceLight1, {
resetMe: true,
lightType: "Sconce Light Hall"
});
var sconceLight2 = Entities.addEntity({
type: "Light",
position: {
x: 540.1,
y: 496.24,
z: 505.57
},
name: "Sconce 2 Light",
dimensions: {
x: 2.545,
y: 2.545,
z: 2.545
},
cutoff: 90,
color: {
red: 217,
green: 146,
blue: 24
}
});
setEntityCustomData(this.resetKey, sconceLight2, {
resetMe: true,
lightType: "Sconce Light Hall"
});
setEntityCustomData(this.lightStateKey, this.entityID, {
on: true
});
},
flipLights: function() {
// flip model to give illusion of light switch being flicked
var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation;
var axis = {
x: 0,
y: 1,
z: 0
};
var dQ = Quat.angleAxis(180, axis);
rotation = Quat.multiply(rotation, dQ);
Entities.editEntity(this.entityID, {
rotation: rotation
});
},
// preload() will be called when the entity has become visible (or known) to the interface
// it gives us a chance to set our local JavaScript object up. In this case it means:
preload: function(entityID) {
this.entityID = entityID;
//The light switch is static, so just cache its position once
this.position = Entities.getEntityProperties(this.entityID, "position").position;
var defaultLightData = {
on: false
};
var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData);
//If light is off, then we create two new lights- at the position of the sconces
if (lightState.on === false) {
this.createLights();
this.flipLights();
}
//If lights are on, do nothing!
},
};
// entity scripts always need to return a newly constructed object of our type
return new LightSwitchHall();
})

View file

@ -62,20 +62,13 @@
this.enableStream = function () {
var position = Entities.getEntityProperties(this.entityId, "position").position;
var animationSettings = JSON.stringify({
fps: 30,
loop: true,
firstFrame: 1,
lastFrame: 10000,
running: true
});
var PI = 3.141593;
var DEG_TO_RAD = PI / 180.0;
this.paintStream = Entities.addEntity({
type: "ParticleEffect",
name: "streamEffect",
animationSettings: animationSettings,
isEmitting: true,
position: position,
textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png",
emitSpeed: 3,
@ -161,4 +154,4 @@
Entities.deleteEntity(this.paintStream);
}
}
});
});

View file

@ -142,8 +142,15 @@ Item {
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded;
text: "Avatar Mixer: " + root.avatarMixerKbps + " kbps, " +
root.avatarMixerPps + "pps";
text: "Avatar Mixer In: " + root.avatarMixerInKbps + " kbps, " +
root.avatarMixerInPps + "pps";
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded;
text: "Avatar Mixer Out: " + root.avatarMixerOutKbps + " kbps, " +
root.avatarMixerOutPps + "pps";
}
Text {
color: root.fontColor;

File diff suppressed because it is too large Load diff

View file

@ -12,6 +12,8 @@
#ifndef hifi_Application_h
#define hifi_Application_h
#include <functional>
#include <QApplication>
#include <QHash>
#include <QImage>
@ -19,103 +21,52 @@
#include <QSet>
#include <QStringList>
#include <QUndoStack>
#include <functional>
#include <AbstractScriptingServicesInterface.h>
#include <AbstractViewStateInterface.h>
#include <EntityEditPacketSender.h>
#include <EntityTreeRenderer.h>
#include <GeometryCache.h>
#include <input-plugins/KeyboardMouseDevice.h>
#include <NodeList.h>
#include <OctreeQuery.h>
#include <OffscreenUi.h>
#include <PhysicalEntitySimulation.h>
#include <PhysicsEngine.h>
#include <plugins/Forward.h>
#include <ScriptEngine.h>
#include <ShapeManager.h>
#include <StDev.h>
#include <udt/PacketHeaders.h>
#include <ViewFrustum.h>
#include <SimpleMovingAverage.h>
#include <StDev.h>
#include <ViewFrustum.h>
#include "AudioClient.h"
#include "avatar/AvatarUpdate.h"
#include "avatar/MyAvatar.h"
#include "Bookmarks.h"
#include "Camera.h"
#include "Environment.h"
#include "FileLogger.h"
#include "gpu/Context.h"
#include "Menu.h"
#include "Physics.h"
#include "Stars.h"
#include "avatar/AvatarUpdate.h"
#include "avatar/Avatar.h"
#include "avatar/MyAvatar.h"
#include "octree/OctreePacketProcessor.h"
#include "render/Engine.h"
#include "scripting/ControllerScriptingInterface.h"
#include "scripting/DialogsManagerScriptingInterface.h"
#include "scripting/WebWindowClass.h"
#include "ui/ApplicationCompositor.h"
#include "ui/ApplicationOverlay.h"
#include "ui/AudioStatsDialog.h"
#include "ui/BandwidthDialog.h"
#include "ui/ModelsBrowser.h"
#include "ui/OctreeStatsDialog.h"
#include "ui/SnapshotShareDialog.h"
#include "ui/LodToolsDialog.h"
#include "ui/LogDialog.h"
#include "ui/overlays/Overlays.h"
#include "ui/ApplicationOverlay.h"
#include "ui/ApplicationCompositor.h"
#include "ui/OctreeStatsDialog.h"
#include "ui/OverlayConductor.h"
#include "ui/overlays/Overlays.h"
#include "ui/RunningScriptsWidget.h"
#include "ui/SnapshotShareDialog.h"
#include "ui/ToolWindow.h"
#include "octree/OctreePacketProcessor.h"
#include "UndoStackScriptingInterface.h"
#include "gpu/Context.h"
#include "render/Engine.h"
class QGLWidget;
class QKeyEvent;
class QMouseEvent;
class QSystemTrayIcon;
class QTouchEvent;
class QWheelEvent;
class OffscreenGlCanvas;
class GLCanvas;
class FaceTracker;
class MainWindow;
class Node;
class ScriptEngine;
namespace gpu {
class Context;
typedef std::shared_ptr<Context> ContextPointer;
}
static const QString SNAPSHOT_EXTENSION = ".jpg";
static const QString SVO_EXTENSION = ".svo";
static const QString SVO_JSON_EXTENSION = ".svo.json";
static const QString JS_EXTENSION = ".js";
static const QString FST_EXTENSION = ".fst";
static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees
static const float BILLBOARD_DISTANCE = 5.56f; // meters
static const int MIRROR_VIEW_TOP_PADDING = 5;
static const int MIRROR_VIEW_LEFT_PADDING = 10;
static const int MIRROR_VIEW_WIDTH = 265;
static const int MIRROR_VIEW_HEIGHT = 215;
static const float MIRROR_FULLSCREEN_DISTANCE = 0.389f;
static const float MIRROR_REARVIEW_DISTANCE = 0.722f;
static const float MIRROR_REARVIEW_BODY_DISTANCE = 2.56f;
static const float MIRROR_FIELD_OF_VIEW = 30.0f;
static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS_PER_SECOND;
static const QString INFO_HELP_PATH = "html/interface-welcome.html";
static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-commands.html";
#ifdef Q_OS_WIN
static const UINT UWM_IDENTIFY_INSTANCES =
@ -130,24 +81,19 @@ class Application;
#endif
#define qApp (static_cast<Application*>(QCoreApplication::instance()))
typedef bool (Application::* AcceptURLMethod)(const QString &);
class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface {
Q_OBJECT
// TODO? Get rid of those
friend class OctreePacketProcessor;
friend class DatagramProcessor;
friend class PluginContainerProxy;
public:
static Application* getInstance() { return qApp; } // TODO: replace fully by qApp
static const glm::vec3& getPositionForPath() { return getInstance()->_myAvatar->getPosition(); }
static glm::quat getOrientationForPath() { return getInstance()->_myAvatar->getOrientation(); }
static glm::vec3 getPositionForAudio() { return getInstance()->_myAvatar->getPositionForAudio(); }
static glm::quat getOrientationForAudio() { return getInstance()->_myAvatar->getOrientationForAudio(); }
// FIXME? Empty methods, do we still need them?
static void initPlugins();
static void shutdownPlugins();
Application(int& argc, char** argv, QElapsedTimer &startup_time);
Application(int& argc, char** argv, QElapsedTimer& startup_time);
~Application();
void postLambdaEvent(std::function<void()> f);
@ -161,27 +107,6 @@ public:
void paintGL();
void resizeGL();
void resizeEvent(QResizeEvent * size);
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
void focusOutEvent(QFocusEvent* event);
void focusInEvent(QFocusEvent* event);
void mouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mousePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0);
void touchBeginEvent(QTouchEvent* event);
void touchEndEvent(QTouchEvent* event);
void touchUpdateEvent(QTouchEvent* event);
void wheelEvent(QWheelEvent* event);
void dropEvent(QDropEvent* event);
void dragEnterEvent(QDragEnterEvent* event);
bool event(QEvent* event);
bool eventFilter(QObject* object, QEvent* event);
@ -190,7 +115,6 @@ public:
QSize getDeviceSize() const;
bool hasFocus() const;
PickRay computePickRay() const;
PickRay computeViewPickRay(float xRatio, float yRatio) const;
bool isThrottleRendering() const;
@ -208,49 +132,29 @@ public:
EntityTreeRenderer* getEntities() { return &_entities; }
QUndoStack* getUndoStack() { return &_undoStack; }
MainWindow* getWindow() { return _window; }
OctreeQuery& getOctreeQuery() { return _octreeQuery; }
EntityTreePointer getEntityClipboard() { return _entityClipboard; }
EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; }
EntityEditPacketSender* getEntityEditPacketSender() { return &_entityEditSender; }
bool isMousePressed() const { return _mousePressed; }
bool isMouseHidden() const { return !_cursorVisible; }
const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; }
const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; }
bool mouseOnScreen() const;
ivec2 getMouse() const;
ivec2 getTrueMouse() const;
ivec2 getMouseDragStarted() const;
ivec2 getTrueMouseDragStarted() const;
// TODO get rid of these and use glm types directly
int getMouseX() const { return getMouse().x; }
int getMouseY() const { return getMouse().y; }
int getTrueMouseX() const { return getTrueMouse().x; }
int getTrueMouseY() const { return getTrueMouse().y; }
int getMouseDragStartedX() const { return getMouseDragStarted().x; }
int getMouseDragStartedY() const { return getMouseDragStarted().y; }
int getTrueMouseDragStartedX() const { return getTrueMouseDragStarted().x; }
int getTrueMouseDragStartedY() const { return getTrueMouseDragStarted().y; }
bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; }
FaceTracker* getActiveFaceTracker();
FaceTracker* getSelectedFaceTracker();
QSystemTrayIcon* getTrayIcon() { return _trayIcon; }
ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; }
const ApplicationOverlay& getApplicationOverlay() const { return _applicationOverlay; }
ApplicationCompositor& getApplicationCompositor() { return _compositor; }
const ApplicationCompositor& getApplicationCompositor() const { return _compositor; }
Overlays& getOverlays() { return _overlays; }
bool isForeground() const { return _isForeground; }
float getFps() const { return _fps; }
float getFieldOfView() { return _fieldOfView.get(); }
void setFieldOfView(float fov) { _fieldOfView.set(fov); }
bool importSVOFromURL(const QString& urlString);
void setFieldOfView(float fov);
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
@ -259,21 +163,14 @@ public:
virtual AbstractControllerScriptingInterface* getControllerScriptingInterface() { return &_controllerScriptingInterface; }
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine);
void resetProfile(const QString& username);
virtual bool shouldRenderMesh(float largestDimension, float distanceToCamera);
QImage renderAvatarBillboard(RenderArgs* renderArgs);
void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false, bool billboard = false);
virtual const glm::vec3& getShadowDistances() const { return _shadowDistances; }
virtual ViewFrustum* getCurrentViewFrustum() { return getDisplayViewFrustum(); }
virtual QThread* getMainThread() { return thread(); }
virtual float getSizeScale() const;
virtual int getBoundaryLevelAdjust() const;
virtual PickRay computePickRay(float x, float y) const;
virtual const glm::vec3& getAvatarPosition() const { return _myAvatar->getPosition(); }
virtual const glm::vec3& getAvatarPosition() const;
virtual void overrideEnvironmentData(const EnvironmentData& newData) { _environment.override(newData); }
virtual void endOverrideEnvironmentData() { _environment.endOverride(); }
virtual qreal getDevicePixelRatio();
@ -283,8 +180,6 @@ public:
DisplayPlugin* getActiveDisplayPlugin();
const DisplayPlugin* getActiveDisplayPlugin() const;
public:
FileLogger* getLogger() { return _logger; }
glm::vec2 getViewportDimensions() const;
@ -293,11 +188,8 @@ public:
QStringList getRunningScripts() { return _scriptEnginesHash.keys(); }
ScriptEngine* getScriptEngine(const QString& scriptHash) { return _scriptEnginesHash.value(scriptHash, NULL); }
bool isLookingAtMyAvatar(AvatarSharedPointer avatar);
float getRenderResolutionScale() const;
int getRenderAmbientLight() const;
bool isAboutToQuit() const { return _aboutToQuit; }
@ -306,7 +198,6 @@ public:
// TODO: carry that information on the Camera as a setting
bool isHMDMode() const;
glm::mat4 getHMDSensorPose() const;
glm::mat4 getEyePose(int eye) const;
glm::mat4 getEyeOffset(int eye) const;
glm::mat4 getEyeProjection(int eye) const;
@ -318,7 +209,6 @@ public:
QString getScriptsLocation();
void setScriptsLocation(const QString& scriptsLocation);
void initializeAcceptedFiles();
bool canAcceptURL(const QString& url);
bool acceptURL(const QString& url);
@ -326,30 +216,20 @@ public:
int getMaxOctreePacketsPerSecond();
render::ScenePointer getMain3DScene() { return _main3DScene; }
render::EnginePointer getRenderEngine() { return _renderEngine; }
render::ScenePointer getMain3DScene() const { return _main3DScene; }
render::EnginePointer getRenderEngine() { return _renderEngine; }
gpu::ContextPointer getGPUContext() const { return _gpuContext; }
const QRect& getMirrorViewRect() const { return _mirrorViewRect; }
void updateMyAvatarLookAtPosition();
AvatarUpdate* getAvatarUpdater() { return _avatarUpdate; }
MyAvatar* getMyAvatar() { return _myAvatar; }
float getAvatarSimrate();
void setAvatarSimrateSample(float sample);
float getAverageSimsPerSecond();
signals:
/// Fired when we're simulating; allows external parties to hook in.
void simulating(float deltaTime);
/// Fired when the import window is closed
void importDone();
void scriptLocationChanged(const QString& newPath);
void svoImportRequested(const QString& url);
@ -357,23 +237,12 @@ signals:
void checkBackgroundDownloads();
void domainConnectionRefused(const QString& reason);
void headURLChanged(const QString& newValue, const QString& modelName);
void bodyURLChanged(const QString& newValue, const QString& modelName);
void fullAvatarURLChanged(const QString& newValue, const QString& modelName);
void beforeAboutToQuit();
void activeDisplayPluginChanged();
public slots:
void setSessionUUID(const QUuid& sessionUUID);
void domainChanged(const QString& domainHostname);
void updateWindowTitle();
void nodeAdded(SharedNodePointer node);
void nodeKilled(SharedNodePointer node);
void packetSent(quint64 length);
void updateDisplayMode();
void updateInputModes();
QVector<EntityItemID> pasteEntities(float x, float y, float z);
bool exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs);
bool exportEntities(const QString& filename, float x, float y, float z, float scale);
@ -383,64 +252,50 @@ public slots:
void loadDialog();
void loadScriptURLDialog();
void toggleLogDialog();
bool acceptSnapshot(const QString& urlString);
bool askToSetAvatarUrl(const QString& url);
bool askToLoadScript(const QString& scriptFilenameOrURL);
ScriptEngine* loadScript(const QString& scriptFilename = QString(), bool isUserLoaded = true,
bool loadScriptFromEditor = false, bool activateMainWindow = false, bool reload = false);
void reloadScript(const QString& scriptName, bool isUserLoaded = true);
void scriptFinished(const QString& scriptName);
void stopAllScripts(bool restart = false);
bool stopScript(const QString& scriptHash, bool restart = false);
void reloadAllScripts();
void reloadOneScript(const QString& scriptName);
void loadDefaultScripts();
void toggleRunningScriptsWidget();
void saveScripts();
void showFriendsWindow();
void friendsWindowClosed();
void packageModel();
void openUrl(const QUrl& url);
void updateMyAvatarTransform();
void setAvatarUpdateThreading();
void setAvatarUpdateThreading(bool isThreaded);
void setRawAvatarUpdateThreading();
void setRawAvatarUpdateThreading(bool isThreaded);
void domainSettingsReceived(const QJsonObject& domainSettingsObject);
void setThrottleFPSEnabled();
bool isThrottleFPSEnabled() { return _isThrottleFPSEnabled; }
void resetSensors();
void setActiveFaceTracker();
#ifdef HAVE_IVIEWHMD
void setActiveEyeTracker();
void calibrateEyeTracker1Point();
void calibrateEyeTracker3Points();
void calibrateEyeTracker5Points();
#endif
void aboutApp();
void showEditEntitiesHelp();
void loadSettings();
void saveSettings();
void notifyPacketVersionMismatch();
void handleDomainConnectionDeniedPacket(QSharedPointer<NLPacket> packet);
void cameraMenuChanged();
void reloadResourceCaches();
void crashApplication();
void rotationModeChanged();
void runTests();
private slots:
void clearDomainOctreeDetails();
void checkFPS();
@ -452,27 +307,37 @@ private slots:
void connectedToDomain(const QString& hostname);
void rotationModeChanged();
void closeMirrorView();
void restoreMirrorView();
void shrinkMirrorView();
void manageRunningScriptsWidgetVisibility(bool shown);
void runTests();
void audioMuteToggled();
void faceTrackerMuteToggled();
void setCursorVisible(bool visible);
void activeChanged(Qt::ApplicationState state);
void domainSettingsReceived(const QJsonObject& domainSettingsObject);
void handleDomainConnectionDeniedPacket(QSharedPointer<NLPacket> packet);
void notifyPacketVersionMismatch();
void loadSettings();
void saveSettings();
void scriptFinished(const QString& scriptName);
void saveScripts();
void reloadScript(const QString& scriptName, bool isUserLoaded = true);
bool acceptSnapshot(const QString& urlString);
bool askToSetAvatarUrl(const QString& url);
bool askToLoadScript(const QString& scriptFilenameOrURL);
void setSessionUUID(const QUuid& sessionUUID);
void domainChanged(const QString& domainHostname);
void updateWindowTitle();
void nodeAdded(SharedNodePointer node);
void nodeKilled(SharedNodePointer node);
void packetSent(quint64 length);
void updateDisplayMode();
void updateInputModes();
private:
void resetCameras(Camera& camera, const glm::uvec2& size);
void sendPingPackets();
void initDisplay();
void init();
@ -487,15 +352,8 @@ private:
// Various helper functions called during update()
void updateLOD();
void updateMouseRay();
void updateThreads(float deltaTime);
void updateCamera(float deltaTime);
void updateDialogs(float deltaTime);
void updateCursor(float deltaTime);
Avatar* findLookatTargetAvatar(glm::vec3& eyePosition, QUuid &nodeUUID);
void renderLookatIndicator(glm::vec3 pointOfInterest);
void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
@ -504,12 +362,45 @@ private:
void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard = false);
void setMenuShortcutsEnabled(bool enabled);
static void attachNewHeadToNode(Node *newNode);
static void* networkReceive(void* args); // network receive thread
int sendNackPackets();
void takeSnapshot();
MyAvatar* getMyAvatar() const;
void checkSkeleton();
void initializeAcceptedFiles();
int getRenderAmbientLight() const;
void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false, bool billboard = false);
bool importSVOFromURL(const QString& urlString);
int processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode);
void trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket);
void resizeEvent(QResizeEvent* size);
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
void focusOutEvent(QFocusEvent* event);
void focusInEvent(QFocusEvent* event);
void mouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mousePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0);
void touchBeginEvent(QTouchEvent* event);
void touchEndEvent(QTouchEvent* event);
void touchUpdateEvent(QTouchEvent* event);
void wheelEvent(QWheelEvent* event);
void dropEvent(QDropEvent* event);
void dragEnterEvent(QDragEnterEvent* event);
bool _dependencyManagerIsSetup;
@ -520,21 +411,15 @@ private:
MainWindow* _window;
ToolWindow* _toolWindow;
WebWindowClass* _friendsWindow;
QUndoStack _undoStack;
UndoStackScriptingInterface _undoStackScriptingInterface;
glm::vec3 _gravity;
// Frame Rate Measurement
int _frameCount;
float _fps;
QElapsedTimer _applicationStartupTime;
QElapsedTimer _timerStart;
QElapsedTimer _lastTimeUpdated;
bool _justStarted;
ShapeManager _shapeManager;
PhysicalEntitySimulation _entitySimulation;
@ -550,12 +435,9 @@ private:
ViewFrustum _shadowViewFrustum;
quint64 _lastQueriedTime;
float _trailingAudioLoudness;
OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers
KeyboardMouseDevice* _keyboardMouseDevice{ nullptr }; // Default input device, the good old keyboard mouse and maybe touchpad
MyAvatar* _myAvatar; // TODO: move this and relevant code to AvatarManager (or MyAvatar as the case may be)
AvatarUpdate* _avatarUpdate {nullptr};
SimpleMovingAverage _avatarSimsPerSecond {10};
int _avatarSimsPerSecondReport {0};
@ -564,37 +446,19 @@ private:
Camera _mirrorCamera; // Cammera for mirror view
QRect _mirrorViewRect;
Setting::Handle<bool> _firstRun;
Setting::Handle<QString> _previousScriptLocation;
Setting::Handle<QString> _scriptsLocationHandle;
Setting::Handle<float> _fieldOfView;
Setting::Handle<bool> _firstRun;
Setting::Handle<QString> _previousScriptLocation;
Setting::Handle<QString> _scriptsLocationHandle;
Setting::Handle<float> _fieldOfView;
float _scaleMirror;
float _rotateMirror;
float _raiseMirror;
static const int CASCADED_SHADOW_MATRIX_COUNT = 4;
glm::mat4 _shadowMatrices[CASCADED_SHADOW_MATRIX_COUNT];
glm::vec3 _shadowDistances;
Environment _environment;
bool _cursorVisible;
ivec2 _mouseDragStarted;
quint64 _lastMouseMove;
bool _lastMouseMoveWasSimulated;
glm::vec3 _mouseRayOrigin;
glm::vec3 _mouseRayDirection;
vec2 _touchAvg;
vec2 _touchDragStartedAvg;
bool _isTouchPressed; // true if multitouch has been pressed (clear when finished)
bool _mousePressed; // true if mouse has been pressed (clear when finished)
QSet<int> _keysPressed;
bool _enableProcessOctreeThread;
@ -605,9 +469,6 @@ private:
StDev _idleLoopStdev;
float _idleLoopMeasuredJitter;
int processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode);
void trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket);
NodeToJurisdictionMap _entityServerJurisdictions;
NodeToOctreeSceneStats _octreeServerSceneStats;
@ -617,8 +478,6 @@ private:
FileLogger* _logger;
void takeSnapshot();
TouchEvent _lastTouchEvent;
RunningScriptsWidget* _runningScriptsWidget;
@ -626,12 +485,8 @@ private:
bool _runningScriptsWidgetWasVisible;
QString _scriptsLocation;
QSystemTrayIcon* _trayIcon;
quint64 _lastNackTime;
quint64 _lastSendDownstreamAudioStats;
bool _isThrottleFPSEnabled;
bool _aboutToQuit;
@ -643,9 +498,8 @@ private:
QTimer _settingsTimer;
GLCanvas* _glWidget{ nullptr };
void checkSkeleton();
typedef bool (Application::* AcceptURLMethod)(const QString &);
QHash<QString, AcceptURLMethod> _acceptedExtensions;
QList<QString> _domainConnectionRefusals;
@ -668,10 +522,7 @@ private:
int _oldHandMouseY[2];
bool _oldHandLeftClick[2];
bool _oldHandRightClick[2];
int _numFramesSinceLastResize = 0;
bool _overlayEnabled = true;
QRect _savedGeometry;
DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface();
EntityItemID _keyboardFocusedItem;
@ -682,8 +533,6 @@ private:
quint64 _lastSimsPerSecondUpdate = 0;
bool _isForeground = true; // starts out assumed to be in foreground
bool _inPaint = false;
friend class PluginContainerProxy;
};
#endif // hifi_Application_h

View file

@ -59,7 +59,7 @@ protected:
_lastRollTime = now;
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
file.close();
qDebug() << "Rolled log file: " << newFileName;
qDebug() << "Rolled log file:" << newFileName;
}
}
}

View file

@ -17,6 +17,7 @@
#include <QWindow>
#include "MainWindow.h"
#include "Menu.h"
static QGLFormat& getDesiredGLFormat() {
// Specify an OpenGL 3.3 format using the Core profile.
@ -62,16 +63,16 @@ void GLCanvas::paintGL() {
// FIXME - I'm not sure why this still remains, it appears as if this GLCanvas gets a single paintGL call near
// the beginning of the application starting up. I'm not sure if we really need to call Application::paintGL()
// in this case, since the display plugins eventually handle all the painting
if (!Application::getInstance()->getWindow()->isMinimized() || !Application::getInstance()->isThrottleFPSEnabled()) {
Application::getInstance()->paintGL();
bool isThrottleFPSEnabled = Menu::getInstance()->isOptionChecked(MenuOption::ThrottleFPSIfNotFocus);
if (!qApp->getWindow()->isMinimized() || !isThrottleFPSEnabled) {
qApp->paintGL();
}
}
void GLCanvas::resizeGL(int width, int height) {
Application::getInstance()->resizeGL();
qApp->resizeGL();
}
int updateTime = 0;
bool GLCanvas::event(QEvent* event) {
switch (event->type()) {
case QEvent::MouseMove:
@ -95,7 +96,7 @@ bool GLCanvas::event(QEvent* event) {
break;
case QEvent::Paint:
// Ignore paint events that occur after we've decided to quit
if (Application::getInstance()->isAboutToQuit()) {
if (qApp->isAboutToQuit()) {
return true;
}
break;

View file

@ -26,14 +26,14 @@ LODManager::LODManager() {
}
float LODManager::getLODDecreaseFPS() {
if (Application::getInstance()->isHMDMode()) {
if (qApp->isHMDMode()) {
return getHMDLODDecreaseFPS();
}
return getDesktopLODDecreaseFPS();
}
float LODManager::getLODIncreaseFPS() {
if (Application::getInstance()->isHMDMode()) {
if (qApp->isHMDMode()) {
return getHMDLODIncreaseFPS();
}
return getDesktopLODIncreaseFPS();

View file

@ -31,6 +31,7 @@ MainWindow::MainWindow(QWidget* parent) :
_windowState("WindowState", 0)
{
setAcceptDrops(true);
_trayIcon.show();
}
void MainWindow::restoreGeometry() {

View file

@ -13,6 +13,7 @@
#define __hifi__MainWindow__
#include <QMainWindow>
#include <QSystemTrayIcon>
#include <SettingHandle.h>
@ -42,6 +43,7 @@ protected:
private:
Setting::Handle<QRect> _windowGeometry;
Setting::Handle<int> _windowState;
QSystemTrayIcon _trayIcon;
};
#endif /* defined(__hifi__MainWindow__) */

View file

@ -332,8 +332,7 @@ Menu::Menu() {
ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight8, 0, false));
ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight9, 0, false));
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ThrottleFPSIfNotFocus, 0, true,
qApp, SLOT(setThrottleFPSEnabled()));
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ThrottleFPSIfNotFocus, 0, true);
MenuWrapper* resolutionMenu = renderOptionsMenu->addMenu(MenuOption::RenderResolution);
QActionGroup* resolutionGroup = new QActionGroup(resolutionMenu);
@ -465,7 +464,7 @@ Menu::Menu() {
MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands");
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandMouseInput, 0, true);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::EnableHandMouseInput, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LowVelocityFilter, 0, true,
qApp, SLOT(setLowVelocityFilter(bool)));
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false);

View file

@ -204,7 +204,7 @@ namespace MenuOption {
const QString FrameTimer = "Show Timer";
const QString FullscreenMirror = "Fullscreen Mirror";
const QString GlowWhenSpeaking = "Glow When Speaking";
const QString HandMouseInput = "Enable Hand Mouse Input";
const QString EnableHandMouseInput = "Enable Hand Controller Mouse Input";
const QString IncreaseAvatarSize = "Increase Avatar Size";
const QString IndependentMode = "Independent Mode";
const QString InputMenu = "Avatar>Input Devices";

View file

@ -16,8 +16,11 @@ PluginContainerProxy::PluginContainerProxy() {
Plugin::setContainer(this);
}
PluginContainerProxy::~PluginContainerProxy() {
}
bool PluginContainerProxy::isForeground() {
return qApp->_isForeground && !qApp->getWindow()->isMinimized();
return qApp->isForeground() && !qApp->getWindow()->isMinimized();
}
void PluginContainerProxy::addMenu(const QString& menuName) {
@ -78,7 +81,7 @@ void PluginContainerProxy::setIsOptionChecked(const QString& path, bool checked)
// Additionally, setting fullscreen isn't hiding the menu on windows
// make it useless for stereoscopic modes.
void PluginContainerProxy::setFullscreen(const QScreen* target, bool hideMenu) {
auto _window = qApp->_window;
auto _window = qApp->getWindow();
if (!_window->isFullScreen()) {
_savedGeometry = _window->geometry();
}
@ -101,7 +104,7 @@ void PluginContainerProxy::setFullscreen(const QScreen* target, bool hideMenu) {
}
void PluginContainerProxy::unsetFullscreen(const QScreen* avoid) {
auto _window = qApp->_window;
auto _window = qApp->getWindow();
_window->showNormal();
QRect targetGeometry = _savedGeometry;
@ -151,3 +154,7 @@ void PluginContainerProxy::showDisplayPluginsTools() {
QGLWidget* PluginContainerProxy::getPrimarySurface() {
return qApp->_glWidget;
}
const DisplayPlugin* PluginContainerProxy::getActiveDisplayPlugin() const {
return qApp->getActiveDisplayPlugin();
}

View file

@ -11,6 +11,7 @@
class PluginContainerProxy : public QObject, PluginContainer {
Q_OBJECT
PluginContainerProxy();
virtual ~PluginContainerProxy();
virtual void addMenu(const QString& menuName) override;
virtual void removeMenu(const QString& menuName) override;
virtual QAction* addMenuItem(const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") override;
@ -23,6 +24,8 @@ class PluginContainerProxy : public QObject, PluginContainer {
virtual void requestReset() override;
virtual QGLWidget* getPrimarySurface() override;
virtual bool isForeground() override;
virtual const DisplayPlugin* getActiveDisplayPlugin() const override;
QRect _savedGeometry{ 10, 120, 800, 600 };
friend class Application;

View file

@ -9,6 +9,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "Util.h"
#include <iostream>
#include <cstring>
#include <time.h>
@ -19,17 +21,17 @@
#include <glm/gtx/quaternion.hpp>
#include <glm/detail/func_common.hpp>
#include <QElapsedTimer>
#include <QThread>
#include <ByteCountCoding.h>
#include <SharedUtil.h>
#include <DeferredLightingEffect.h>
#include <GeometryCache.h>
#include <OctreeConstants.h>
#include <SharedUtil.h>
#include "world.h"
#include "Application.h"
#include "InterfaceLogging.h"
#include "Util.h"
#include "world.h"
using namespace std;

View file

@ -72,7 +72,7 @@ namespace render {
avatarPtr->setDisplayingLookatTarget(renderLookAtTarget);
if (avatarPtr->isInitialized() && args) {
avatarPtr->render(args, Application::getInstance()->getCamera()->getPosition());
avatarPtr->render(args, qApp->getCamera()->getPosition());
}
}
}
@ -98,7 +98,7 @@ Avatar::Avatar(RigPointer rig) :
_voiceSphereID(GeometryCache::UNKNOWN_ID)
{
// we may have been created in the network thread, but we live in the main thread
moveToThread(Application::getInstance()->thread());
moveToThread(qApp->thread());
// give the pointer to our head to inherited _headData variable from AvatarData
_headData = static_cast<HeadData*>(new Head(this));
@ -152,7 +152,7 @@ void Avatar::simulate(float deltaTime) {
// update the avatar's position according to its referential
if (_referential) {
if (_referential->hasExtraData()) {
EntityTreePointer tree = Application::getInstance()->getEntities()->getTree();
EntityTreePointer tree = qApp->getEntities()->getTree();
switch (_referential->type()) {
case Referential::MODEL:
_referential = new ModelReferential(_referential,
@ -189,7 +189,7 @@ void Avatar::simulate(float deltaTime) {
// simple frustum check
float boundingRadius = getBillboardSize();
bool inViewFrustum = Application::getInstance()->getViewFrustum()->sphereInFrustum(_position, boundingRadius) !=
bool inViewFrustum = qApp->getViewFrustum()->sphereInFrustum(_position, boundingRadius) !=
ViewFrustum::OUTSIDE;
{
@ -245,6 +245,14 @@ void Avatar::simulate(float deltaTime) {
measureMotionDerivatives(deltaTime);
}
bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) {
const float HEAD_SPHERE_RADIUS = 0.1f;
glm::vec3 theirLookAt = dynamic_pointer_cast<Avatar>(avatar)->getHead()->getLookAtPosition();
glm::vec3 myEyePosition = getHead()->getEyePosition();
return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getScale());
}
void Avatar::slamPosition(const glm::vec3& newPosition) {
setPosition(newPosition);
_positionDeltaAccumulator = glm::vec3(0.0f);
@ -388,9 +396,9 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
float boundingRadius = getBillboardSize();
ViewFrustum* frustum = nullptr;
if (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) {
frustum = Application::getInstance()->getShadowViewFrustum();
frustum = qApp->getShadowViewFrustum();
} else {
frustum = Application::getInstance()->getDisplayViewFrustum();
frustum = qApp->getDisplayViewFrustum();
}
if (frustum->sphereInFrustum(getPosition(), boundingRadius) == ViewFrustum::OUTSIDE) {
@ -539,9 +547,14 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
const float DISPLAYNAME_DISTANCE = 20.0f;
setShowDisplayName(distanceToTarget < DISPLAYNAME_DISTANCE);
auto cameraMode = Application::getInstance()->getCamera()->getMode();
auto cameraMode = qApp->getCamera()->getMode();
if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) {
renderDisplayName(batch, *renderArgs->_viewFrustum, renderArgs->_viewport);
auto& frustum = *renderArgs->_viewFrustum;
auto textPosition = getDisplayNamePosition();
if (frustum.pointInFrustum(textPosition, true) == ViewFrustum::INSIDE) {
renderDisplayName(batch, frustum, textPosition);
}
}
endRender();
}
@ -566,7 +579,7 @@ void Avatar::fixupModelsInScene() {
// check to see if when we added our models to the scene they were ready, if they were not ready, then
// fix them up in the scene
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
render::PendingChanges pendingChanges;
if (_skeletonModel.isRenderable() && _skeletonModel.needsFixupInScene()) {
_skeletonModel.removeFromScene(scene, pendingChanges);
@ -653,7 +666,7 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) {
}
// rotate about vertical to face the camera
glm::quat rotation = getOrientation();
glm::vec3 cameraVector = glm::inverse(rotation) * (Application::getInstance()->getCamera()->getPosition() - _position);
glm::vec3 cameraVector = glm::inverse(rotation) * (qApp->getCamera()->getPosition() - _position);
rotation = rotation * glm::angleAxis(atan2f(-cameraVector.x, -cameraVector.z), glm::vec3(0.0f, 1.0f, 0.0f));
// compute the size from the billboard camera parameters and scale
@ -677,120 +690,85 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) {
}
float Avatar::getBillboardSize() const {
return _scale * BILLBOARD_DISTANCE * tanf(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f));
return _scale * BILLBOARD_DISTANCE * glm::tan(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f));
}
#ifdef DEBUG
void debugValue(const QString& str, const glm::vec3& value) {
if (glm::any(glm::isnan(value)) || glm::any(glm::isinf(value))) {
qCWarning(interfaceapp) << "debugValue() " << str << value;
}
};
void debugValue(const QString& str, const float& value) {
if (glm::isnan(value) || glm::isinf(value)) {
qCWarning(interfaceapp) << "debugValue() " << str << value;
}
};
#define DEBUG_VALUE(str, value) debugValue(str, value)
#else
#define DEBUG_VALUE(str, value)
#endif
glm::vec3 Avatar::getDisplayNamePosition() const {
glm::vec3 namePosition(0.0f);
glm::vec3 bodyUpDirection = getBodyUpDirection();
DEBUG_VALUE("bodyUpDirection =", bodyUpDirection);
if (getSkeletonModel().getNeckPosition(namePosition)) {
namePosition += getBodyUpDirection() * getHeadHeight() * 1.1f;
float headHeight = getHeadHeight();
DEBUG_VALUE("namePosition =", namePosition);
DEBUG_VALUE("headHeight =", headHeight);
static const float SLIGHTLY_ABOVE = 1.1f;
namePosition += bodyUpDirection * headHeight * SLIGHTLY_ABOVE;
} else {
const float HEAD_PROPORTION = 0.75f;
namePosition = _position + getBodyUpDirection() * (getBillboardSize() * HEAD_PROPORTION);
float billboardSize = getBillboardSize();
DEBUG_VALUE("_position =", _position);
DEBUG_VALUE("billboardSize =", billboardSize);
namePosition = _position + bodyUpDirection * (billboardSize * HEAD_PROPORTION);
}
#ifdef DEBUG
// TODO: Temporary logging to track cause of invalid scale value; remove once cause has been fixed.
// See other TODO below.
if (glm::isnan(namePosition.x) || glm::isnan(namePosition.y) || glm::isnan(namePosition.z)
|| glm::isinf(namePosition.x) || glm::isinf(namePosition.y) || glm::isinf(namePosition.z)) {
qDebug() << "namePosition =" << namePosition;
glm::vec3 tempPosition(0.0f);
if (getSkeletonModel().getNeckPosition(tempPosition)) {
qDebug() << "getBodyUpDirection() =" << getBodyUpDirection();
qDebug() << "getHeadHeight() =" << getHeadHeight();
} else {
qDebug() << "_position =" << _position;
qDebug() << "getBodyUpDirection() =" << getBodyUpDirection();
qDebug() << "getBillboardSize() =" << getBillboardSize();
}
if (glm::any(glm::isnan(namePosition)) || glm::any(glm::isinf(namePosition))) {
qCWarning(interfaceapp) << "Invalid display name position" << namePosition
<< ", setting is to (0.0f, 0.5f, 0.0f)";
namePosition = glm::vec3(0.0f, 0.5f, 0.0f);
}
#endif
return namePosition;
}
Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, float fontSize, const glm::ivec4& viewport) const {
Transform result;
// We assume textPosition is whithin the frustum
glm::vec3 textPosition = getDisplayNamePosition();
// Compute viewProjection matrix
glm::mat4 projMat, viewMat;
Transform view;
frustum.evalProjectionMatrix(projMat);
frustum.evalViewTransform(view);
glm::mat4 viewProj = projMat * view.getInverseMatrix(viewMat);
// Used to determine correct scale
glm::vec3 testPoint0 = textPosition;
glm::vec3 testPoint1 = testPoint0 + glm::normalize(frustum.getUp());
// testPoints projections
glm::vec4 p0 = viewProj * glm::vec4(testPoint0, 1.0);
glm::vec4 p1 = viewProj * glm::vec4(testPoint1, 1.0);
float windowSizeY = viewport.w;
const float DESIRED_HIGHT_ON_SCREEN = 20; // In pixels (this is double on retinas)
// Projected point are between -1.0f and 1.0f, hence 0.5f * windowSizeY
float pixelHeight = 0.5f * windowSizeY * glm::abs((p1.y / p1.w) - (p0.y / p0.w)); //
// Handles pixel density (especially for macs retina displays)
float devicePixelRatio = (float)qApp->getDevicePixelRatio() * qApp->getRenderResolutionScale(); // pixels / unit
// Compute correct scale to apply
float scale = DESIRED_HIGHT_ON_SCREEN / (fontSize * pixelHeight) * devicePixelRatio;
#ifdef DEBUG
// TODO: Temporary logging to track cause of invalid scale value; remove once cause has been fixed.
// Problem is probably due to an invalid getDisplayNamePosition(). See extra logging above.
if (scale == 0.0f || glm::isnan(scale) || glm::isinf(scale)) {
if (scale == 0.0f) {
qDebug() << "ASSERT because scale == 0.0f";
}
if (glm::isnan(scale)) {
qDebug() << "ASSERT because isnan(scale)";
}
if (glm::isinf(scale)) {
qDebug() << "ASSERT because isinf(scale)";
}
qDebug() << "textPosition =" << textPosition;
qDebug() << "projMat =" << projMat;
qDebug() << "viewMat =" << viewMat;
qDebug() << "viewProj =" << viewProj;
qDebug() << "windowSizeY =" << windowSizeY;
qDebug() << "p1 =" << p1;
qDebug() << "p0 =" << p0;
qDebug() << "qApp->getDevicePixelRatio() =" << qApp->getDevicePixelRatio();
qDebug() << "fontSize =" << fontSize;
qDebug() << "pixelHeight =" << pixelHeight;
qDebug() << "devicePixelRatio =" << devicePixelRatio;
}
#endif
// Compute pixel alignment offset
float clipToPix = 0.5f * windowSizeY / p1.w; // Got from clip to pixel coordinates
glm::vec4 screenPos = clipToPix * p1; // in pixels coords
glm::vec4 screenOffset = (glm::round(screenPos) - screenPos) / clipToPix; // in clip coords
glm::vec3 worldOffset = glm::vec3(screenOffset.x, screenOffset.y, 0.0f) / (float)pixelHeight;
Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const {
Q_ASSERT_X(frustum.pointInFrustum(textPosition, true) == ViewFrustum::INSIDE,
"Avatar::calculateDisplayNameTransform", "Text not in viewfrustum.");
glm::vec3 toFrustum = frustum.getPosition() - textPosition;
// Compute orientation
glm::vec3 dPosition = frustum.getPosition() - getPosition();
// If x and z are 0, atan(x, z) is undefined, so default to 0 degrees
float yawRotation = dPosition.x == 0.0f && dPosition.z == 0.0f ? 0.0f : glm::atan(dPosition.x, dPosition.z);
// If x and z are 0, atan(x, z) adais undefined, so default to 0 degrees
const float yawRotation = (toFrustum.x == 0.0f && toFrustum.z == 0.0f) ? 0.0f : glm::atan(toFrustum.x, toFrustum.z);
glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f));
// Set transform (The order IS important)
// Compute correct scale to apply
static const float DESIRED_HEIGHT_RAD = glm::radians(1.5f);
float scale = glm::length(toFrustum) * glm::tan(DESIRED_HEIGHT_RAD);
// Set transform
Transform result;
result.setTranslation(textPosition);
result.setRotation(orientation); // Always face the screen
result.postTranslate(worldOffset); // Pixel alignment
result.setScale(scale);
// raise by half the scale up so that textPosition be the bottom
result.postTranslate(Vectors::UP / 2.0f);
return result;
}
void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::ivec4& viewport) const {
void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::vec3& textPosition) const {
bool shouldShowReceiveStats = DependencyManager::get<AvatarManager>()->shouldShowReceiveStats() && !isMyAvatar();
// If we have nothing to draw, or it's totally transparent, or it's too close or behind the camera, return
const float CLIP_DISTANCE = 0.2f;
static const float CLIP_DISTANCE = 0.2f;
if ((_displayName.isEmpty() && !shouldShowReceiveStats) || _displayNameAlpha == 0.0f
|| (glm::dot(frustum.getDirection(), getDisplayNamePosition() - frustum.getPosition()) <= CLIP_DISTANCE)) {
return;
@ -810,39 +788,45 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co
}
// Compute display name extent/position offset
glm::vec2 extent = renderer->computeExtent(renderedDisplayName);
QRect nameDynamicRect = QRect(0, 0, (int)extent.x, (int)extent.y);
const int text_x = -nameDynamicRect.width() / 2;
const int text_y = -nameDynamicRect.height() / 2;
// Compute background position/size
static const float SLIGHTLY_IN_FRONT = 0.1f;
const int border = 0.1f * nameDynamicRect.height();
const int left = text_x - border;
const int bottom = text_y - border;
const int width = nameDynamicRect.width() + 2.0f * border;
const int height = nameDynamicRect.height() + 2.0f * border;
const int bevelDistance = 0.1f * height;
// Display name and background colors
glm::vec4 textColor(0.93f, 0.93f, 0.93f, _displayNameAlpha);
glm::vec4 backgroundColor(0.2f, 0.2f, 0.2f,
(_displayNameAlpha / DISPLAYNAME_ALPHA) * DISPLAYNAME_BACKGROUND_ALPHA);
// Compute display name transform
auto textTransform = calculateDisplayNameTransform(frustum, renderer->getFontSize(), viewport);
batch.setModelTransform(textTransform);
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, false, true, true, true);
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(batch, left, bottom, width, height,
bevelDistance, backgroundColor);
// Render actual name
QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit();
// Render text slightly in front to avoid z-fighting
textTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_IN_FRONT * renderer->getFontSize()));
batch.setModelTransform(textTransform);
renderer->draw(batch, text_x, -text_y, nameUTF8.data(), textColor);
const glm::vec2 extent = renderer->computeExtent(renderedDisplayName);
if (!glm::any(glm::isCompNull(extent, EPSILON))) {
const QRect nameDynamicRect = QRect(0, 0, (int)extent.x, (int)extent.y);
const int text_x = -nameDynamicRect.width() / 2;
const int text_y = -nameDynamicRect.height() / 2;
// Compute background position/size
static const float SLIGHTLY_IN_FRONT = 0.1f;
static const float BORDER_RELATIVE_SIZE = 0.1f;
static const float BEVEL_FACTOR = 0.1f;
const int border = BORDER_RELATIVE_SIZE * nameDynamicRect.height();
const int left = text_x - border;
const int bottom = text_y - border;
const int width = nameDynamicRect.width() + 2.0f * border;
const int height = nameDynamicRect.height() + 2.0f * border;
const int bevelDistance = BEVEL_FACTOR * height;
// Display name and background colors
glm::vec4 textColor(0.93f, 0.93f, 0.93f, _displayNameAlpha);
glm::vec4 backgroundColor(0.2f, 0.2f, 0.2f,
(_displayNameAlpha / DISPLAYNAME_ALPHA) * DISPLAYNAME_BACKGROUND_ALPHA);
// Compute display name transform
auto textTransform = calculateDisplayNameTransform(frustum, textPosition);
// Test on extent above insures abs(height) > 0.0f
textTransform.postScale(1.0f / height);
batch.setModelTransform(textTransform);
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, false, true, true, true);
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(batch, left, bottom, width, height,
bevelDistance, backgroundColor);
// Render actual name
QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit();
// Render text slightly in front to avoid z-fighting
textTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_IN_FRONT * renderer->getFontSize()));
batch.setModelTransform(textTransform);
renderer->draw(batch, text_x, -text_y, nameUTF8.data(), textColor);
}
}
void Avatar::setSkeletonOffset(const glm::vec3& offset) {

View file

@ -37,6 +37,9 @@ static const float SCALING_RATIO = .05f;
static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1
static const float RESCALING_TOLERANCE = .02f;
static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees
static const float BILLBOARD_DISTANCE = 5.56f; // meters
extern const float CHAT_MESSAGE_SCALE;
extern const float CHAT_MESSAGE_HEIGHT;
@ -77,7 +80,7 @@ public:
typedef render::Payload<AvatarData> Payload;
typedef std::shared_ptr<render::Item::PayloadInterface> PayloadPointer;
void init();
void simulate(float deltaTime);
@ -198,7 +201,9 @@ protected:
glm::vec3 _worldUpDirection;
float _stringLength;
bool _moving; ///< set when position is changing
bool isLookingAtMe(AvatarSharedPointer avatar);
// protected methods...
glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; }
@ -212,8 +217,8 @@ protected:
float getPelvisFloatingHeight() const;
glm::vec3 getDisplayNamePosition() const;
Transform calculateDisplayNameTransform(const ViewFrustum& frustum, float fontSize, const glm::ivec4& viewport) const;
void renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::ivec4& viewport) const;
Transform calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const;
void renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::vec3& textPosition) const;
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f);
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const;
virtual void fixupModelsInScene();

View file

@ -81,7 +81,7 @@ void AvatarManager::init() {
connect(DependencyManager::get<SceneScriptingInterface>().data(), &SceneScriptingInterface::shouldRenderAvatarsChanged, this, &AvatarManager::updateAvatarRenderStatus, Qt::QueuedConnection);
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
render::PendingChanges pendingChanges;
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderAvatars()) {
_myAvatar->addToScene(_myAvatar, scene, pendingChanges);
@ -146,7 +146,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
const float SHRINK_RATE = 0.9f;
const float MIN_FADE_SCALE = 0.001f;
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
render::PendingChanges pendingChanges;
while (fadingIterator != _avatarFades.end()) {
auto avatar = std::static_pointer_cast<Avatar>(*fadingIterator);
@ -171,7 +171,7 @@ AvatarSharedPointer AvatarManager::newSharedAvatar() {
// virtual
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
auto avatar = std::dynamic_pointer_cast<Avatar>(AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer));
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
render::PendingChanges pendingChanges;
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderAvatars()) {
avatar->addToScene(avatar, scene, pendingChanges);
@ -328,7 +328,7 @@ void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) {
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderAvatars()) {
for (auto avatarData : _avatarHash) {
auto avatar = std::dynamic_pointer_cast<Avatar>(avatarData);
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
render::PendingChanges pendingChanges;
avatar->addToScene(avatar, scene, pendingChanges);
scene->enqueuePendingChanges(pendingChanges);
@ -336,7 +336,7 @@ void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) {
} else {
for (auto avatarData : _avatarHash) {
auto avatar = std::dynamic_pointer_cast<Avatar>(avatarData);
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
render::PendingChanges pendingChanges;
avatar->removeFromScene(avatar, scene, pendingChanges);
scene->enqueuePendingChanges(pendingChanges);

View file

@ -29,11 +29,11 @@ AvatarUpdate::AvatarUpdate() : GenericThread(), _lastAvatarUpdate(0) {
void AvatarUpdate::synchronousProcess() {
// Keep our own updated value, so that our asynchronous code can consult it.
_isHMDMode = Application::getInstance()->isHMDMode();
_headPose = Application::getInstance()->getActiveDisplayPlugin()->getHeadPose();
_isHMDMode = qApp->isHMDMode();
_headPose = qApp->getActiveDisplayPlugin()->getHeadPose();
if (_updateBillboard) {
Application::getInstance()->getMyAvatar()->doUpdateBillboard();
DependencyManager::get<AvatarManager>()->getMyAvatar()->doUpdateBillboard();
}
if (!isThreaded()) {
@ -47,7 +47,7 @@ bool AvatarUpdate::process() {
quint64 deltaMicroseconds = start - _lastAvatarUpdate;
_lastAvatarUpdate = start;
float deltaSeconds = (float) deltaMicroseconds / (float) USECS_PER_SECOND;
Application::getInstance()->setAvatarSimrateSample(1.0f / deltaSeconds);
qApp->setAvatarSimrateSample(1.0f / deltaSeconds);
QSharedPointer<AvatarManager> manager = DependencyManager::get<AvatarManager>();
MyAvatar* myAvatar = manager->getMyAvatar();
@ -57,7 +57,7 @@ bool AvatarUpdate::process() {
manager->updateOtherAvatars(deltaSeconds);
myAvatar->startUpdate();
Application::getInstance()->updateMyAvatarLookAtPosition();
qApp->updateMyAvatarLookAtPosition();
// Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
manager->updateMyAvatar(deltaSeconds);
myAvatar->endUpdate();

View file

@ -94,7 +94,7 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
// Only use face trackers when not playing back a recording.
if (!myAvatar->isPlaying()) {
FaceTracker* faceTracker = Application::getInstance()->getActiveFaceTracker();
FaceTracker* faceTracker = qApp->getActiveFaceTracker();
_isFaceTrackerConnected = faceTracker != NULL && !faceTracker->isMuted();
if (_isFaceTrackerConnected) {
_blendshapeCoefficients = faceTracker->getBlendshapeCoefficients();

View file

@ -25,6 +25,7 @@
#include <AudioClient.h>
#include <DependencyManager.h>
#include <display-plugins/DisplayPlugin.h>
#include <FSTReader.h>
#include <GeometryUtil.h>
#include <NodeList.h>
#include <udt/PacketHeaders.h>
@ -37,6 +38,7 @@
#include "devices/Faceshift.h"
#include "Application.h"
#include "AvatarManager.h"
#include "Environment.h"
@ -124,7 +126,7 @@ MyAvatar::~MyAvatar() {
}
QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) {
CameraMode mode = Application::getInstance()->getCamera()->getMode();
CameraMode mode = qApp->getCamera()->getMode();
if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) {
// fake the avatar position that is sent up to the AvatarMixer
glm::vec3 oldPosition = _position;
@ -384,7 +386,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
return;
}
FaceTracker* tracker = Application::getInstance()->getActiveFaceTracker();
FaceTracker* tracker = qApp->getActiveFaceTracker();
bool inFacetracker = tracker && !tracker->isMuted();
if (inHmd) {
@ -398,7 +400,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
estimatedPosition = tracker->getHeadTranslation();
_trackedHeadPosition = estimatedPosition;
estimatedRotation = glm::degrees(safeEulerAngles(tracker->getHeadRotation()));
if (Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) {
if (qApp->getCamera()->getMode() == CAMERA_MODE_MIRROR) {
// Invert yaw and roll when in mirror mode
// NOTE: this is kinda a hack, it's the same hack we use to make the head tilt. But it's not really a mirror
// it just makes you feel like you're looking in a mirror because the body movements of the avatar appear to
@ -436,8 +438,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
head->setDeltaYaw(estimatedRotation.y);
head->setDeltaRoll(estimatedRotation.z);
} else {
float magnifyFieldOfView = qApp->getFieldOfView() /
_realWorldFieldOfView.get();
float magnifyFieldOfView = qApp->getViewFrustum()->getFieldOfView() / _realWorldFieldOfView.get();
head->setDeltaPitch(estimatedRotation.x * magnifyFieldOfView);
head->setDeltaYaw(estimatedRotation.y * magnifyFieldOfView);
head->setDeltaRoll(estimatedRotation.z);
@ -446,16 +447,16 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
// Update torso lean distance based on accelerometer data
const float TORSO_LENGTH = 0.5f;
glm::vec3 relativePosition = estimatedPosition - glm::vec3(0.0f, -TORSO_LENGTH, 0.0f);
const float MAX_LEAN = 45.0f;
// Invert left/right lean when in mirror mode
// NOTE: this is kinda a hack, it's the same hack we use to make the head tilt. But it's not really a mirror
// it just makes you feel like you're looking in a mirror because the body movements of the avatar appear to
// match your body movements.
if ((inHmd || inFacetracker) && Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) {
if ((inHmd || inFacetracker) && qApp->getCamera()->getMode() == CAMERA_MODE_MIRROR) {
relativePosition.x = -relativePosition.x;
}
const float MAX_LEAN = 45.0f;
head->setLeanSideways(glm::clamp(glm::degrees(atanf(relativePosition.x * _leanScale / TORSO_LENGTH)),
-MAX_LEAN, MAX_LEAN));
head->setLeanForward(glm::clamp(glm::degrees(atanf(relativePosition.z * _leanScale / TORSO_LENGTH)),
@ -548,7 +549,7 @@ void MyAvatar::clearReferential() {
}
bool MyAvatar::setModelReferential(const QUuid& id) {
EntityTreePointer tree = Application::getInstance()->getEntities()->getTree();
EntityTreePointer tree = qApp->getEntities()->getTree();
changeReferential(new ModelReferential(id, tree, this));
if (_referential->isValid()) {
return true;
@ -559,7 +560,7 @@ bool MyAvatar::setModelReferential(const QUuid& id) {
}
bool MyAvatar::setJointReferential(const QUuid& id, int jointIndex) {
EntityTreePointer tree = Application::getInstance()->getEntities()->getTree();
EntityTreePointer tree = qApp->getEntities()->getTree();
changeReferential(new JointReferential(jointIndex, id, tree, this));
if (!_referential->isValid()) {
return true;
@ -866,7 +867,7 @@ void MyAvatar::setEnableDebugDrawAnimPose(bool isEnabled) {
}
void MyAvatar::setEnableMeshVisible(bool isEnabled) {
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
_skeletonModel.setVisibleInScene(isEnabled, scene);
}
@ -1015,7 +1016,7 @@ void MyAvatar::updateLookAtTargetAvatar() {
_targetAvatarPosition = glm::vec3(0.0f);
glm::vec3 lookForward = getHead()->getFinalOrientationInWorldFrame() * IDENTITY_FRONT;
glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition();
glm::vec3 cameraPosition = qApp->getCamera()->getPosition();
float smallestAngleTo = glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES) / 2.0f;
const float KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR = 1.3f;
@ -1033,7 +1034,7 @@ void MyAvatar::updateLookAtTargetAvatar() {
_targetAvatarPosition = avatarPointer->getPosition();
smallestAngleTo = angleTo;
}
if (Application::getInstance()->isLookingAtMyAvatar(avatar)) {
if (isLookingAtMe(avatar)) {
// Alter their gaze to look directly at my camera; this looks more natural than looking at my avatar's face.
glm::vec3 lookAtPosition = avatar->getHead()->getLookAtPosition(); // A position, in world space, on my avatar.
@ -1045,11 +1046,11 @@ void MyAvatar::updateLookAtTargetAvatar() {
// When not in HMD, these might both answer identity (i.e., the bridge of the nose). That's ok.
// By my inpsection of the code and live testing, getEyeOffset and getEyePose are the same. (Application hands identity as offset matrix.)
// This might be more work than needed for any given use, but as we explore different formulations, we go mad if we don't work in world space.
glm::mat4 leftEye = Application::getInstance()->getEyeOffset(Eye::Left);
glm::mat4 rightEye = Application::getInstance()->getEyeOffset(Eye::Right);
glm::mat4 leftEye = qApp->getEyeOffset(Eye::Left);
glm::mat4 rightEye = qApp->getEyeOffset(Eye::Right);
glm::vec3 leftEyeHeadLocal = glm::vec3(leftEye[3]);
glm::vec3 rightEyeHeadLocal = glm::vec3(rightEye[3]);
auto humanSystem = Application::getInstance()->getViewFrustum();
auto humanSystem = qApp->getViewFrustum();
glm::vec3 humanLeftEye = humanSystem->getPosition() + (humanSystem->getOrientation() * leftEyeHeadLocal);
glm::vec3 humanRightEye = humanSystem->getPosition() + (humanSystem->getOrientation() * rightEyeHeadLocal);
@ -1075,7 +1076,7 @@ void MyAvatar::updateLookAtTargetAvatar() {
*/
// And now we can finally add that offset to the camera.
glm::vec3 corrected = Application::getInstance()->getViewFrustum()->getPosition() + gazeOffset;
glm::vec3 corrected = qApp->getViewFrustum()->getPosition() + gazeOffset;
avatar->getHead()->setCorrectedLookAtPosition(corrected);
@ -1182,7 +1183,7 @@ void MyAvatar::clearJointAnimationPriorities() {
void MyAvatar::setFaceModelURL(const QUrl& faceModelURL) {
Avatar::setFaceModelURL(faceModelURL);
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
getHead()->getFaceModel().setVisibleInScene(_prevShouldDrawHead, scene);
_billboardValid = false;
}
@ -1190,7 +1191,7 @@ void MyAvatar::setFaceModelURL(const QUrl& faceModelURL) {
void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
Avatar::setSkeletonModelURL(skeletonModelURL);
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
_billboardValid = false;
_skeletonModel.setVisibleInScene(true, scene);
_headBoneSet.clear();
@ -1248,7 +1249,7 @@ void MyAvatar::setAttachmentData(const QVector<AttachmentData>& attachmentData)
}
glm::vec3 MyAvatar::getSkeletonPosition() const {
CameraMode mode = Application::getInstance()->getCamera()->getMode();
CameraMode mode = qApp->getCamera()->getMode();
if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) {
// The avatar is rotated PI about the yAxis, so we have to correct for it
// to get the skeleton offset contribution in the world-frame.
@ -1349,14 +1350,16 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, fl
// This is drawing the lookat vectors from our avatar to wherever we're looking.
if (qApp->isHMDMode()) {
glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition();
glm::vec3 cameraPosition = qApp->getCamera()->getPosition();
glm::mat4 leftEyePose = Application::getInstance()->getActiveDisplayPlugin()->getEyePose(Eye::Left);
glm::vec3 leftEyePosition = glm::vec3(leftEyePose[3]);
glm::mat4 rightEyePose = Application::getInstance()->getActiveDisplayPlugin()->getEyePose(Eye::Right);
glm::vec3 rightEyePosition = glm::vec3(rightEyePose[3]);
glm::mat4 headPose = Application::getInstance()->getActiveDisplayPlugin()->getHeadPose();
glm::vec3 headPosition = glm::vec3(headPose[3]);
glm::mat4 headPose = qApp->getActiveDisplayPlugin()->getHeadPose();
glm::mat4 leftEyePose = qApp->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Left);
leftEyePose = leftEyePose * headPose;
glm::vec3 leftEyePosition = extractTranslation(leftEyePose);
glm::mat4 rightEyePose = qApp->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Right);
rightEyePose = rightEyePose * headPose;
glm::vec3 rightEyePosition = extractTranslation(rightEyePose);
glm::vec3 headPosition = extractTranslation(headPose);
getHead()->renderLookAts(renderArgs,
cameraPosition + getOrientation() * (leftEyePosition - headPosition),
@ -1431,7 +1434,7 @@ void MyAvatar::destroyAnimGraph() {
void MyAvatar::preRender(RenderArgs* renderArgs) {
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
const bool shouldDrawHead = shouldRenderHead(renderArgs);
if (_skeletonModel.initWhenReady(scene)) {
@ -1486,13 +1489,13 @@ const float RENDER_HEAD_CUTOFF_DISTANCE = 0.50f;
bool MyAvatar::cameraInsideHead() const {
const Head* head = getHead();
const glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition();
const glm::vec3 cameraPosition = qApp->getCamera()->getPosition();
return glm::length(cameraPosition - head->getEyePosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * _scale);
}
bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
return ((renderArgs->_renderMode != RenderArgs::DEFAULT_RENDER_MODE) ||
(Application::getInstance()->getCamera()->getMode() != CAMERA_MODE_FIRST_PERSON) ||
(qApp->getCamera()->getMode() != CAMERA_MODE_FIRST_PERSON) ||
!cameraInsideHead());
}
@ -1536,7 +1539,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
glm::vec3 euler = glm::eulerAngles(localOrientation) * DEGREES_PER_RADIAN;
//Invert yaw and roll when in mirror mode
if (Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) {
if (qApp->getCamera()->getMode() == CAMERA_MODE_MIRROR) {
YAW(euler) *= -1.0f;
ROLL(euler) *= -1.0f;
}
@ -1961,7 +1964,7 @@ glm::vec3 MyAvatar::getPositionForAudio() {
case AudioListenerMode::FROM_HEAD:
return getHead()->getPosition();
case AudioListenerMode::FROM_CAMERA:
return Application::getInstance()->getCamera()->getPosition();
return qApp->getCamera()->getPosition();
case AudioListenerMode::CUSTOM:
return _customListenPosition;
}
@ -1973,7 +1976,7 @@ glm::quat MyAvatar::getOrientationForAudio() {
case AudioListenerMode::FROM_HEAD:
return getHead()->getFinalOrientationInWorldFrame();
case AudioListenerMode::FROM_CAMERA:
return Application::getInstance()->getCamera()->getOrientation();
return qApp->getCamera()->getOrientation();
case AudioListenerMode::CUSTOM:
return _customListenOrientation;
}

View file

@ -135,7 +135,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
headParams.isInHMD = true;
// get HMD position from sensor space into world space, and back into model space
AnimPose avatarToWorld(glm::vec3(1), myAvatar->getOrientation(), myAvatar->getPosition());
AnimPose avatarToWorld(glm::vec3(1.0f), myAvatar->getOrientation(), myAvatar->getPosition());
glm::mat4 worldToAvatar = glm::inverse((glm::mat4)avatarToWorld);
glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
glm::mat4 hmdMat = worldToAvatar * worldHMDMat;

View file

@ -10,6 +10,7 @@
//
#include "3DConnexionClient.h"
#include "Menu.h"
#include "UserActivityLogger.h"
const float MAX_AXIS = 75.0f; // max forward = 2x speed

View file

@ -16,8 +16,6 @@
#include <input-plugins/UserInputMapper.h>
#include "InterfaceLogging.h"
#include "Application.h"
#ifndef HAVE_3DCONNEXIONCLIENT
class ConnexionClient : public QObject {

View file

@ -10,6 +10,7 @@
//
#include "MotionTracker.h"
#include "GLMHelpers.h"
// glm::mult(mat43, mat43) just the composition of the 2 matrices assuming they are in fact mat44 with the last raw = { 0, 0, 0, 1 }
@ -177,7 +178,7 @@ void MotionTracker::Frame::setRotation(const glm::quat& rotation) {
}
void MotionTracker::Frame::getRotation(glm::quat& rotation) const {
rotation = glm::quat_cast( _transform);
rotation = glm::quat_cast(_transform);
}
void MotionTracker::Frame::setTranslation(const glm::vec3& translation) {
@ -185,6 +186,6 @@ void MotionTracker::Frame::setTranslation(const glm::vec3& translation) {
}
void MotionTracker::Frame::getTranslation(glm::vec3& translation) const {
translation = glm::vec3(_transform[3]);
translation = extractTranslation(_transform);
}

View file

@ -250,7 +250,7 @@ void RealSense::update() {
void RealSense::loadRSSDKFile() {
QString locationDir(QStandardPaths::displayName(QStandardPaths::DesktopLocation));
QString fileNameString = QFileDialog::getOpenFileName(Application::getInstance()->getWindow(), tr("Open RSSDK clip"),
QString fileNameString = QFileDialog::getOpenFileName(qApp->getWindow(), tr("Open RSSDK clip"),
locationDir,
tr("RSSDK Recordings (*.rssdk)"));
if (!fileNameString.isEmpty()) {

View file

@ -33,11 +33,10 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
const int WAY_BEHIND = 300;
if (packetsToProcessCount() > WAY_BEHIND && Application::getInstance()->getLogger()->extraDebugging()) {
if (packetsToProcessCount() > WAY_BEHIND && qApp->getLogger()->extraDebugging()) {
qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount());
}
Application* app = Application::getInstance();
bool wasStatsPacket = false;
PacketType octreePacketType = packet->getType();
@ -46,7 +45,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
// immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first
// then process any remaining bytes as if it was another packet
if (octreePacketType == PacketType::OctreeStats) {
int statsMessageLength = app->processOctreeStats(*packet, sendingNode);
int statsMessageLength = qApp->processOctreeStats(*packet, sendingNode);
wasStatsPacket = true;
int piggybackBytes = packet->getPayloadSize() - statsMessageLength;
@ -84,7 +83,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
return; // bail since piggyback version doesn't match
}
app->trackIncomingOctreePacket(*packet, sendingNode, wasStatsPacket);
qApp->trackIncomingOctreePacket(*packet, sendingNode, wasStatsPacket);
// seek back to beginning of packet after tracking
packet->seek(0);
@ -92,13 +91,13 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
switch(packetType) {
case PacketType::EntityErase: {
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
app->_entities.processEraseMessage(*packet, sendingNode);
qApp->getEntities()->processEraseMessage(*packet, sendingNode);
}
} break;
case PacketType::EntityData: {
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
app->_entities.processDatagram(*packet, sendingNode);
qApp->getEntities()->processDatagram(*packet, sendingNode);
}
} break;

View file

@ -15,12 +15,12 @@ ClipboardScriptingInterface::ClipboardScriptingInterface() {
}
float ClipboardScriptingInterface::getClipboardContentsLargestDimension() {
return Application::getInstance()->getEntityClipboard()->getContentsLargestDimension();
return qApp->getEntityClipboard()->getContentsLargestDimension();
}
bool ClipboardScriptingInterface::exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs) {
bool retVal;
QMetaObject::invokeMethod(Application::getInstance(), "exportEntities", Qt::BlockingQueuedConnection,
QMetaObject::invokeMethod(qApp, "exportEntities", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, retVal),
Q_ARG(const QString&, filename),
Q_ARG(const QVector<EntityItemID>&, entityIDs));
@ -29,7 +29,7 @@ bool ClipboardScriptingInterface::exportEntities(const QString& filename, const
bool ClipboardScriptingInterface::exportEntities(const QString& filename, float x, float y, float z, float s) {
bool retVal;
QMetaObject::invokeMethod(Application::getInstance(), "exportEntities", Qt::BlockingQueuedConnection,
QMetaObject::invokeMethod(qApp, "exportEntities", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, retVal),
Q_ARG(const QString&, filename),
Q_ARG(float, x),
@ -41,7 +41,7 @@ bool ClipboardScriptingInterface::exportEntities(const QString& filename, float
bool ClipboardScriptingInterface::importEntities(const QString& filename) {
bool retVal;
QMetaObject::invokeMethod(Application::getInstance(), "importEntities", Qt::BlockingQueuedConnection,
QMetaObject::invokeMethod(qApp, "importEntities", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, retVal),
Q_ARG(const QString&, filename));
return retVal;
@ -49,7 +49,7 @@ bool ClipboardScriptingInterface::importEntities(const QString& filename) {
QVector<EntityItemID> ClipboardScriptingInterface::pasteEntities(glm::vec3 position) {
QVector<EntityItemID> retVal;
QMetaObject::invokeMethod(Application::getInstance(), "pasteEntities", Qt::BlockingQueuedConnection,
QMetaObject::invokeMethod(qApp, "pasteEntities", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QVector<EntityItemID>, retVal),
Q_ARG(float, position.x),
Q_ARG(float, position.y),

View file

@ -378,7 +378,7 @@ void ControllerScriptingInterface::releaseJoystick(int joystickIndex) {
}
glm::vec2 ControllerScriptingInterface::getViewportDimensions() const {
return Application::getInstance()->getUiSize();
return qApp->getUiSize();
}
AbstractInputController* ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) {

View file

@ -18,10 +18,10 @@
#include "MainWindow.h"
int DesktopScriptingInterface::getWidth() {
QSize size = Application::getInstance()->getWindow()->windowHandle()->screen()->virtualSize();
QSize size = qApp->getWindow()->windowHandle()->screen()->virtualSize();
return size.width();
}
int DesktopScriptingInterface::getHeight() {
QSize size = Application::getInstance()->getWindow()->windowHandle()->screen()->virtualSize();
QSize size = qApp->getWindow()->windowHandle()->screen()->virtualSize();
return size.height();
}

View file

@ -143,5 +143,5 @@ void GlobalServicesScriptingInterface::updateDownloadInfo() {
}
void GlobalServicesScriptingInterface::editFriends() {
QMetaObject::invokeMethod(Application::getInstance(), "showFriendsWindow");
QMetaObject::invokeMethod(qApp, "showFriendsWindow");
}

View file

@ -10,50 +10,75 @@
//
#include "HMDScriptingInterface.h"
#include <QtScript/QScriptContext>
#include "display-plugins/DisplayPlugin.h"
#include <avatar/AvatarManager.h>
#include "Application.h"
HMDScriptingInterface& HMDScriptingInterface::getInstance() {
static HMDScriptingInterface sharedInstance;
return sharedInstance;
}
bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const {
Camera* camera = Application::getInstance()->getCamera();
glm::vec3 position = camera->getPosition();
glm::quat orientation = camera->getOrientation();
glm::vec3 direction = orientation * glm::vec3(0.0f, 0.0f, -1.0f);
const auto& compositor = Application::getInstance()->getApplicationCompositor();
return compositor.calculateRayUICollisionPoint(position, direction, result);
HMDScriptingInterface::HMDScriptingInterface() {
}
QScriptValue HMDScriptingInterface::getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine) {
glm::vec3 hudIntersection;
if ((&HMDScriptingInterface::getInstance())->getHUDLookAtPosition3D(hudIntersection)) {
auto instance = DependencyManager::get<HMDScriptingInterface>();
if (instance->getHUDLookAtPosition3D(hudIntersection)) {
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
glm::vec3 sphereCenter = myAvatar->getDefaultEyePosition();
glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * (hudIntersection - sphereCenter);
glm::quat rotation = ::rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), direction);
glm::vec3 eulers = ::safeEulerAngles(rotation);
return qScriptValueFromValue<glm::vec2>(engine, Application::getInstance()->getApplicationCompositor()
.sphericalToOverlay(glm::vec2(eulers.y, -eulers.x)));
return qScriptValueFromValue<glm::vec2>(engine, qApp->getApplicationCompositor()
.sphericalToOverlay(glm::vec2(eulers.y, -eulers.x)));
}
return QScriptValue::NullValue;
}
QScriptValue HMDScriptingInterface::getHUDLookAtPosition3D(QScriptContext* context, QScriptEngine* engine) {
glm::vec3 result;
if ((&HMDScriptingInterface::getInstance())->getHUDLookAtPosition3D(result)) {
auto instance = DependencyManager::get<HMDScriptingInterface>();
if (instance->getHUDLookAtPosition3D(result)) {
return qScriptValueFromValue<glm::vec3>(engine, result);
}
return QScriptValue::NullValue;
}
float HMDScriptingInterface::getIPD() const {
return Application::getInstance()->getActiveDisplayPlugin()->getIPD();
void HMDScriptingInterface::toggleMagnifier() {
qApp->getApplicationCompositor().toggleMagnifier();
}
bool HMDScriptingInterface::getMagnifier() const {
return qApp->getApplicationCompositor().hasMagnifier();
}
bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const {
Camera* camera = qApp->getCamera();
glm::vec3 position = camera->getPosition();
glm::quat orientation = camera->getOrientation();
glm::vec3 direction = orientation * glm::vec3(0.0f, 0.0f, -1.0f);
const auto& compositor = qApp->getApplicationCompositor();
return compositor.calculateRayUICollisionPoint(position, direction, result);
}
glm::mat4 HMDScriptingInterface::getWorldHMDMatrix() const {
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
return myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
}
glm::vec3 HMDScriptingInterface::getPosition() const {
if (qApp->getActiveDisplayPlugin()->isHmd()) {
return extractTranslation(getWorldHMDMatrix());
}
return glm::vec3();
}
glm::quat HMDScriptingInterface::getOrientation() const {
if (qApp->getActiveDisplayPlugin()->isHmd()) {
return glm::normalize(glm::quat_cast(getWorldHMDMatrix()));
}
return glm::quat();
}

View file

@ -12,32 +12,38 @@
#ifndef hifi_HMDScriptingInterface_h
#define hifi_HMDScriptingInterface_h
#include <QtScript/QScriptValue>
class QScriptContext;
class QScriptEngine;
#include <GLMHelpers.h>
#include <DependencyManager.h>
#include <display-plugins/AbstractHMDScriptingInterface.h>
#include "Application.h"
class HMDScriptingInterface : public QObject {
class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Dependency {
Q_OBJECT
Q_PROPERTY(bool magnifier READ getMagnifier)
Q_PROPERTY(bool active READ isHMDMode)
Q_PROPERTY(float ipd READ getIPD)
Q_PROPERTY(glm::vec3 position READ getPosition)
Q_PROPERTY(glm::quat orientation READ getOrientation)
public:
static HMDScriptingInterface& getInstance();
HMDScriptingInterface();
static QScriptValue getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine);
static QScriptValue getHUDLookAtPosition3D(QScriptContext* context, QScriptEngine* engine);
public slots:
void toggleMagnifier() { Application::getInstance()->getApplicationCompositor().toggleMagnifier(); };
void toggleMagnifier();
private:
HMDScriptingInterface() {};
bool getMagnifier() const { return Application::getInstance()->getApplicationCompositor().hasMagnifier(); };
bool isHMDMode() const { return Application::getInstance()->isHMDMode(); }
float getIPD() const;
bool getMagnifier() const;
// Get the position of the HMD
glm::vec3 getPosition() const;
// Get the orientation of the HMD
glm::quat getOrientation() const;
bool getHUDLookAtPosition3D(glm::vec3& result) const;
glm::mat4 getWorldHMDMatrix() const;
};
#endif // hifi_HMDScriptingInterface_h

View file

@ -9,10 +9,10 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "Application.h"
#include "MenuScriptingInterface.h"
#include "Menu.h"
#include <MenuItemProperties.h>
MenuScriptingInterface* MenuScriptingInterface::getInstance() {
static MenuScriptingInterface sharedInstance;

View file

@ -12,13 +12,10 @@
#ifndef hifi_MenuScriptingInterface_h
#define hifi_MenuScriptingInterface_h
#include <QDebug>
#include <QMutex>
#include <QObject>
#include <QString>
#include "Menu.h"
#include <MenuItemProperties.h>
class MenuItemProperties;
class MenuScriptingInterface : public QObject {
Q_OBJECT

View file

@ -9,10 +9,9 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <SettingHandle.h>
#include "SettingsScriptingInterface.h"
#include <SettingHandle.h>
SettingsScriptingInterface* SettingsScriptingInterface::getInstance() {
static SettingsScriptingInterface sharedInstance;

View file

@ -12,12 +12,9 @@
#ifndef hifi_SettingsScriptingInterface_h
#define hifi_SettingsScriptingInterface_h
#include <QDebug>
#include <QObject>
#include <QString>
#include "Application.h"
class SettingsScriptingInterface : public QObject {
Q_OBJECT
SettingsScriptingInterface() { };

View file

@ -41,7 +41,7 @@ WebWindowClass::WebWindowClass(const QString& title, const QString& url, int wid
_isToolWindow(isToolWindow) {
if (_isToolWindow) {
ToolWindow* toolWindow = Application::getInstance()->getToolWindow();
ToolWindow* toolWindow = qApp->getToolWindow();
auto dockWidget = new QDockWidget(title, toolWindow);
dockWidget->setFeatures(QDockWidget::DockWidgetMovable);
@ -56,7 +56,7 @@ WebWindowClass::WebWindowClass(const QString& title, const QString& url, int wid
_windowWidget = dockWidget;
} else {
auto dialogWidget = new QDialog(Application::getInstance()->getWindow(), Qt::Window);
auto dialogWidget = new QDialog(qApp->getWindow(), Qt::Window);
dialogWidget->setWindowTitle(title);
dialogWidget->resize(width, height);
dialogWidget->installEventFilter(this);
@ -120,7 +120,7 @@ void WebWindowClass::setVisible(bool visible) {
if (visible) {
if (_isToolWindow) {
QMetaObject::invokeMethod(
Application::getInstance()->getToolWindow(), "setVisible", Qt::AutoConnection, Q_ARG(bool, visible));
qApp->getToolWindow(), "setVisible", Qt::AutoConnection, Q_ARG(bool, visible));
} else {
QMetaObject::invokeMethod(_windowWidget, "showNormal", Qt::AutoConnection);
QMetaObject::invokeMethod(_windowWidget, "raise", Qt::AutoConnection);

View file

@ -32,8 +32,8 @@ WindowScriptingInterface::WindowScriptingInterface() :
{
const DomainHandler& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
connect(&domainHandler, &DomainHandler::connectedToDomain, this, &WindowScriptingInterface::domainChanged);
connect(Application::getInstance(), &Application::svoImportRequested, this, &WindowScriptingInterface::svoImportRequested);
connect(Application::getInstance(), &Application::domainConnectionRefused, this, &WindowScriptingInterface::domainConnectionRefused);
connect(qApp, &Application::svoImportRequested, this, &WindowScriptingInterface::svoImportRequested);
connect(qApp, &Application::domainConnectionRefused, this, &WindowScriptingInterface::domainConnectionRefused);
}
WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& title, const QString& url, int width, int height, bool isToolWindow) {
@ -41,13 +41,13 @@ WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& title
}
QScriptValue WindowScriptingInterface::hasFocus() {
return Application::getInstance()->hasFocus();
return qApp->hasFocus();
}
void WindowScriptingInterface::setFocus() {
// It's forbidden to call focus() from another thread.
Application::getInstance()->postLambdaEvent([] {
auto window = Application::getInstance()->getWindow();
qApp->postLambdaEvent([] {
auto window = qApp->getWindow();
window->activateWindow();
window->setFocus();
});
@ -55,20 +55,11 @@ void WindowScriptingInterface::setFocus() {
void WindowScriptingInterface::raiseMainWindow() {
// It's forbidden to call raise() from another thread.
Application::getInstance()->postLambdaEvent([] {
Application::getInstance()->getWindow()->raise();
qApp->postLambdaEvent([] {
qApp->getWindow()->raise();
});
}
void WindowScriptingInterface::setCursorVisible(bool visible) {
QMetaObject::invokeMethod(Application::getInstance(), "setCursorVisible", Qt::BlockingQueuedConnection,
Q_ARG(bool, visible));
}
bool WindowScriptingInterface::isCursorVisible() const {
return !Application::getInstance()->isMouseHidden();
}
void WindowScriptingInterface::setCursorPosition(int x, int y) {
QCursor::setPos(x, y);
}
@ -167,7 +158,7 @@ QScriptValue WindowScriptingInterface::peekNonBlockingFormResult(QScriptValue fo
/// \param const QString& message message to display
/// \return QScriptValue::UndefinedValue
QScriptValue WindowScriptingInterface::showAlert(const QString& message) {
QMessageBox::warning(Application::getInstance()->getWindow(), "", message);
QMessageBox::warning(qApp->getWindow(), "", message);
return QScriptValue::UndefinedValue;
}
@ -175,7 +166,7 @@ QScriptValue WindowScriptingInterface::showAlert(const QString& message) {
/// \param const QString& message message to display
/// \return QScriptValue `true` if 'Yes' was clicked, `false` otherwise
QScriptValue WindowScriptingInterface::showConfirm(const QString& message) {
QMessageBox::StandardButton response = QMessageBox::question(Application::getInstance()->getWindow(), "", message);
QMessageBox::StandardButton response = QMessageBox::question(qApp->getWindow(), "", message);
return QScriptValue(response == QMessageBox::Yes);
}
@ -487,7 +478,7 @@ QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptVal
QDialog* WindowScriptingInterface::createForm(const QString& title, QScriptValue form) {
QDialog* editDialog = new QDialog(Application::getInstance()->getWindow());
QDialog* editDialog = new QDialog(qApp->getWindow());
editDialog->setWindowTitle(title);
bool cancelButton = false;
@ -597,7 +588,7 @@ QDialog* WindowScriptingInterface::createForm(const QString& title, QScriptValue
/// \param const QString& defaultText default text in the text box
/// \return QScriptValue string text value in text box if the dialog was accepted, `null` otherwise.
QScriptValue WindowScriptingInterface::showPrompt(const QString& message, const QString& defaultText) {
QInputDialog promptDialog(Application::getInstance()->getWindow());
QInputDialog promptDialog(qApp->getWindow());
promptDialog.setWindowTitle("");
promptDialog.setLabelText(message);
promptDialog.setTextValue(defaultText);
@ -627,7 +618,7 @@ QScriptValue WindowScriptingInterface::showBrowse(const QString& title, const QS
path = fileInfo.filePath();
}
QFileDialog fileDialog(Application::getInstance()->getWindow(), title, path, nameFilter);
QFileDialog fileDialog(qApp->getWindow(), title, path, nameFilter);
fileDialog.setAcceptMode(acceptMode);
QUrl fileUrl(directory);
if (acceptMode == QFileDialog::AcceptSave) {
@ -657,17 +648,17 @@ QScriptValue WindowScriptingInterface::showS3Browse(const QString& nameFilter) {
}
int WindowScriptingInterface::getInnerWidth() {
return Application::getInstance()->getWindow()->geometry().width();
return qApp->getWindow()->geometry().width();
}
int WindowScriptingInterface::getInnerHeight() {
return Application::getInstance()->getWindow()->geometry().height();
return qApp->getWindow()->geometry().height();
}
int WindowScriptingInterface::getX() {
return Application::getInstance()->getWindow()->x();
return qApp->getWindow()->x();
}
int WindowScriptingInterface::getY() {
return Application::getInstance()->getWindow()->y();
return qApp->getWindow()->y();
}

View file

@ -27,20 +27,17 @@ class WindowScriptingInterface : public QObject, public Dependency {
Q_PROPERTY(int innerHeight READ getInnerHeight)
Q_PROPERTY(int x READ getX)
Q_PROPERTY(int y READ getY)
Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible)
public:
WindowScriptingInterface();
int getInnerWidth();
int getInnerHeight();
int getX();
int getY();
bool isCursorVisible() const;
public slots:
QScriptValue getCursorPositionX();
QScriptValue getCursorPositionY();
void setCursorPosition(int x, int y);
void setCursorVisible(bool visible);
QScriptValue hasFocus();
void setFocus();
void raiseMainWindow();

View file

@ -17,6 +17,7 @@
#include <glm/gtc/type_ptr.hpp>
#include <display-plugins/DisplayPlugin.h>
#include <avatar/AvatarManager.h>
#include <gpu/GLBackend.h>
#include <NumericalConstants.h>
@ -285,7 +286,10 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
mat4 camMat;
_cameraBaseTransform.getMatrix(camMat);
camMat = camMat * qApp->getEyePose(eye);
auto displayPlugin = qApp->getActiveDisplayPlugin();
auto headPose = displayPlugin->getHeadPose();
auto eyeToHead = displayPlugin->getEyeToHeadTransform((Eye)eye);
camMat = (headPose * eyeToHead) * camMat;
batch.setViewportTransform(renderArgs->_viewport);
batch.setViewTransform(camMat);
@ -313,8 +317,8 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
glm::mat4 overlayXfm;
_modelTransform.getMatrix(overlayXfm);
// Only render the hand pointers if the HandMouseInput is enabled
if (Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) {
// Only render the hand pointers if the EnableHandMouseInput is enabled
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) {
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
PalmData& palm = myAvatar->getHand()->getPalms()[i];
@ -346,31 +350,28 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
void ApplicationCompositor::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction) const {
cursorPos *= qApp->getCanvasSize();
const glm::vec2 projection = screenToSpherical(cursorPos);
const glm::vec2 projection = overlayToSpherical(cursorPos);
// The overlay space orientation of the mouse coordinates
const glm::quat orientation(glm::vec3(-projection.y, projection.x, 0.0f));
// FIXME We now have the direction of the ray FROM THE DEFAULT HEAD POSE.
// Now we need to account for the actual camera position relative to the overlay
glm::vec3 overlaySpaceDirection = glm::normalize(orientation * IDENTITY_FRONT);
const glm::quat cursorOrientation(glm::vec3(-projection.y, projection.x, 0.0f));
// The orientation and position of the HEAD, not the overlay
glm::vec3 worldSpaceHeadPosition = qApp->getCamera()->getPosition();
glm::quat worldSpaceOrientation = qApp->getCamera()->getOrientation();
// We need the RAW camera orientation and position, because this is what the overlay is
// rendered relative to
glm::vec3 overlayPosition = qApp->getCamera()->getPosition();
glm::quat overlayOrientation = qApp->getCamera()->getRotation();
auto headPose = qApp->getHMDSensorPose();
auto headOrientation = glm::quat_cast(headPose);
auto headTranslation = extractTranslation(headPose);
auto overlayOrientation = worldSpaceOrientation * glm::inverse(headOrientation);
auto overlayPosition = worldSpaceHeadPosition - (overlayOrientation * headTranslation);
if (Menu::getInstance()->isOptionChecked(MenuOption::StandingHMDSensorMode)) {
overlayPosition = _modelTransform.getTranslation();
overlayOrientation = _modelTransform.getRotation();
}
// Intersection UI overlay space
glm::vec3 worldSpaceDirection = overlayOrientation * overlaySpaceDirection;
glm::vec3 worldSpaceIntersection = (glm::normalize(worldSpaceDirection) * _oculusUIRadius) + overlayPosition;
glm::vec3 worldSpaceHeadPosition = (overlayOrientation * extractTranslation(qApp->getHMDSensorPose())) + overlayPosition;
// Intersection in world space
glm::vec3 worldSpaceIntersection = ((overlayOrientation * (cursorOrientation * Vectors::FRONT)) * _oculusUIRadius) + overlayPosition;
origin = worldSpaceHeadPosition;
direction = glm::normalize(worldSpaceIntersection - worldSpaceHeadPosition);
}
@ -425,17 +426,18 @@ bool ApplicationCompositor::calculateRayUICollisionPoint(const glm::vec3& positi
//Renders optional pointers
void ApplicationCompositor::renderPointers(gpu::Batch& batch) {
if (qApp->isHMDMode() && !qApp->getLastMouseMoveWasSimulated() && !qApp->isMouseHidden()) {
if (qApp->isHMDMode() && !qApp->getLastMouseMoveWasSimulated()) {
//If we are in oculus, render reticle later
auto trueMouse = qApp->getTrueMouse();
trueMouse /= qApp->getCanvasSize();
QPoint position = QPoint(qApp->getTrueMouseX(), qApp->getTrueMouseY());
QPoint position = QPoint(qApp->getTrueMouse().x, qApp->getTrueMouse().y);
_reticlePosition[MOUSE] = position;
_reticleActive[MOUSE] = true;
_magActive[MOUSE] = _magnifier;
_reticleActive[LEFT_CONTROLLER] = false;
_reticleActive[RIGHT_CONTROLLER] = false;
} else if (qApp->getLastMouseMoveWasSimulated() && Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) {
} else if (qApp->getLastMouseMoveWasSimulated()
&& Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) {
//only render controller pointer if we aren't already rendering a mouse pointer
_reticleActive[MOUSE] = false;
_magActive[MOUSE] = false;
@ -682,7 +684,6 @@ glm::vec2 ApplicationCompositor::screenToSpherical(const glm::vec2& screenPos) {
result.y = (screenPos.y / screenSize.y - 0.5f);
result.x *= MOUSE_YAW_RANGE;
result.y *= MOUSE_PITCH_RANGE;
return result;
}
@ -701,13 +702,13 @@ glm::vec2 ApplicationCompositor::sphericalToOverlay(const glm::vec2& sphericalP
result /= _textureFov;
result.x /= _textureAspectRatio;
result += 0.5f;
result *= qApp->getCanvasSize();
result *= qApp->getUiSize();
return result;
}
glm::vec2 ApplicationCompositor::overlayToSpherical(const glm::vec2& overlayPos) const {
glm::vec2 result = overlayPos;
result /= qApp->getCanvasSize();
result /= qApp->getUiSize();
result -= 0.5f;
result *= _textureFov;
result.x *= _textureAspectRatio;

View file

@ -7,13 +7,14 @@
//
#include "Application.h"
#include "AvatarInputs.h"
#include <AudioClient.h>
#include <SettingHandle.h>
#include "Menu.h"
#include "Application.h"
#include "devices/FaceTracker.h"
#include "Menu.h"
HIFI_QML_DEF(AvatarInputs)
@ -106,7 +107,7 @@ void AvatarInputs::update() {
}
void AvatarInputs::toggleCameraMute() {
FaceTracker* faceTracker = Application::getInstance()->getSelectedFaceTracker();
FaceTracker* faceTracker = qApp->getSelectedFaceTracker();
if (faceTracker) {
faceTracker->toggleMute();
}

View file

@ -20,7 +20,7 @@ ChatMessageArea::ChatMessageArea(bool useFixedHeight) : QTextBrowser(), _useFixe
connect(document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged,
this, &ChatMessageArea::updateLayout);
connect(this, &QTextBrowser::anchorClicked, Application::getInstance(), &Application::openUrl);
connect(this, &QTextBrowser::anchorClicked, qApp, &Application::openUrl);
}
void ChatMessageArea::setHtml(const QString& html) {

View file

@ -28,7 +28,7 @@ DataWebDialog::DataWebDialog() {
setPage(new DataWebPage(this));
// have the Application handle external links
connect(this, &QWebView::linkClicked, Application::getInstance(), &Application::openUrl);
connect(this, &QWebView::linkClicked, qApp, &Application::openUrl);
}
DataWebDialog* DataWebDialog::dialogForPath(const QString& path,

View file

@ -34,15 +34,15 @@ void DataWebPage::javaScriptConsoleMessage(const QString& message, int lineNumbe
bool DataWebPage::acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, QWebPage::NavigationType type) {
// Handle hifi:// links and links to files with particular extensions
QString urlString = request.url().toString();
if (Application::getInstance()->canAcceptURL(urlString)) {
if (Application::getInstance()->acceptURL(urlString)) {
if (qApp->canAcceptURL(urlString)) {
if (qApp->acceptURL(urlString)) {
return false; // we handled it, so QWebPage doesn't need to handle it
}
}
// Make hyperlinks with target="_blank" open in user's Web browser
if (type == QWebPage::NavigationTypeLinkClicked && frame == nullptr) {
Application::getInstance()->openUrl(request.url());
qApp->openUrl(request.url());
return false; // We handled it.
}

View file

@ -14,6 +14,7 @@
#include <QMessageBox>
#include <AccountManager.h>
#include <Application.h>
#include <MainWindow.h>
#include <PathUtils.h>
@ -32,6 +33,19 @@
#include "ScriptEditorWindow.h"
#include "UpdateDialog.h"
template<typename T>
void DialogsManager::maybeCreateDialog(QPointer<T>& member) {
if (!member) {
MainWindow* parent = qApp->getWindow();
Q_CHECK_PTR(parent);
member = new T(parent);
Q_CHECK_PTR(member);
if (_hmdToolsDialog && member->windowHandle()) {
_hmdToolsDialog->watchWindow(member->windowHandle());
}
}
}
void DialogsManager::toggleAddressBar() {
AddressBarDialog::toggle();

View file

@ -14,13 +14,10 @@
#include <QPointer>
#include <Application.h>
#include <DependencyManager.h>
#include "HMDToolsDialog.h"
class QAction;
class AnimationsDialog;
class AttachmentsDialog;
class AudioStatsDialog;
@ -78,18 +75,7 @@ private:
DialogsManager() {}
template<typename T>
void maybeCreateDialog(QPointer<T>& member) {
if (!member) {
MainWindow* parent = qApp->getWindow();
Q_CHECK_PTR(parent);
member = new T(parent);
Q_CHECK_PTR(member);
if (_hmdToolsDialog && member->windowHandle()) {
_hmdToolsDialog->watchWindow(member->windowHandle());
}
}
}
void maybeCreateDialog(QPointer<T>& member);
QPointer<AnimationsDialog> _animationsDialog;
QPointer<AttachmentsDialog> _attachmentsDialog;

View file

@ -9,11 +9,11 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <QDesktopWidget>
#include <QDialogButtonBox>
#include <QFormLayout>
#include <QGuiApplication>
#include <QDialogButtonBox>
#include <QDesktopWidget>
#include <QLabel>
#include <QPushButton>
#include <QString>
#include <QScreen>
@ -22,6 +22,7 @@
#include <plugins/PluginManager.h>
#include <display-plugins/DisplayPlugin.h>
#include "Application.h"
#include "MainWindow.h"
#include "Menu.h"
#include "ui/DialogsManager.h"
@ -78,11 +79,11 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) :
// what screens we're allowed on
watchWindow(windowHandle());
auto dialogsManager = DependencyManager::get<DialogsManager>();
if (Application::getInstance()->getRunningScriptsWidget()) {
watchWindow(Application::getInstance()->getRunningScriptsWidget()->windowHandle());
if (qApp->getRunningScriptsWidget()) {
watchWindow(qApp->getRunningScriptsWidget()->windowHandle());
}
if (Application::getInstance()->getToolWindow()) {
watchWindow(Application::getInstance()->getToolWindow()->windowHandle());
if (qApp->getToolWindow()) {
watchWindow(qApp->getToolWindow()->windowHandle());
}
if (dialogsManager->getBandwidthDialog()) {
watchWindow(dialogsManager->getBandwidthDialog()->windowHandle());
@ -110,7 +111,7 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) :
});
// watch for our application window moving screens. If it does we want to update our screen details
QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle();
QWindow* mainWindow = qApp->getWindow()->windowHandle();
connect(mainWindow, &QWindow::screenChanged, [this]{
updateUi();
});
@ -142,7 +143,7 @@ QString HMDToolsDialog::getDebugDetails() const {
results += "Desktop's Primary Screen: " + desktopPrimaryScreen->name() + "\n";
results += "Application Primary Screen: " + QGuiApplication::primaryScreen()->name() + "\n";
QScreen* mainWindowScreen = Application::getInstance()->getWindow()->windowHandle()->screen();
QScreen* mainWindowScreen = qApp->getWindow()->windowHandle()->screen();
results += "Application Main Window Screen: " + mainWindowScreen->name() + "\n";
results += "Total Screens: " + QString::number(QApplication::desktop()->screenCount()) + "\n";
@ -159,15 +160,15 @@ void HMDToolsDialog::toggleHMDMode() {
void HMDToolsDialog::enterHMDMode() {
if (!qApp->isHMDMode()) {
Application::getInstance()->setActiveDisplayPlugin(_hmdPluginName);
Application::getInstance()->getWindow()->activateWindow();
qApp->setActiveDisplayPlugin(_hmdPluginName);
qApp->getWindow()->activateWindow();
}
}
void HMDToolsDialog::leaveHMDMode() {
if (qApp->isHMDMode()) {
Application::getInstance()->setActiveDisplayPlugin(_defaultPluginName);
Application::getInstance()->getWindow()->activateWindow();
qApp->setActiveDisplayPlugin(_defaultPluginName);
qApp->getWindow()->activateWindow();
}
}
@ -200,7 +201,7 @@ void HMDToolsDialog::showEvent(QShowEvent* event) {
void HMDToolsDialog::hideEvent(QHideEvent* event) {
// center the cursor on the main application window
centerCursorOnWidget(Application::getInstance()->getWindow());
centerCursorOnWidget(qApp->getWindow());
}
void HMDToolsDialog::screenCountChanged(int newCount) {
@ -275,7 +276,7 @@ void HMDWindowWatcher::windowScreenChanged(QScreen* screen) {
QScreen* betterScreen = NULL;
QScreen* lastApplicationScreen = _hmdTools->getLastApplicationScreen();
QWindow* appWindow = Application::getInstance()->getWindow()->windowHandle();
QWindow* appWindow = qApp->getWindow()->windowHandle();
QScreen* appScreen = appWindow->screen();
if (_previousScreen && _previousScreen != hmdScreen) {

View file

@ -15,6 +15,7 @@
#include <QDialog>
class HMDWindowWatcher;
class QLabel;
class HMDToolsDialog : public QDialog {
Q_OBJECT

View file

@ -53,7 +53,7 @@ JSConsole::JSConsole(QWidget* parent, ScriptEngine* scriptEngine) :
if (_scriptEngine == NULL) {
_scriptEngine = Application::getInstance()->loadScript(QString(), false);
_scriptEngine = qApp->loadScript(QString(), false);
}
connect(_scriptEngine, SIGNAL(evaluationFinished(QScriptValue, bool)),

View file

@ -20,8 +20,8 @@ MarketplaceDialog::MarketplaceDialog(QQuickItem* parent) : OffscreenQmlDialog(pa
bool MarketplaceDialog::navigationRequested(const QString& url) {
qDebug() << url;
if (Application::getInstance()->canAcceptURL(url)) {
if (Application::getInstance()->acceptURL(url)) {
if (qApp->canAcceptURL(url)) {
if (qApp->acceptURL(url)) {
return false; // we handled it, so QWebPage doesn't need to handle it
}
}

View file

@ -129,7 +129,7 @@ OctreeStatsDialog::~OctreeStatsDialog() {
void OctreeStatsDialog::paintEvent(QPaintEvent* event) {
// Processed Entities Related stats
auto entities = Application::getInstance()->getEntities();
auto entities = qApp->getEntities();
auto entitiesTree = entities->getTree();
// Do this ever paint event... even if we don't update
@ -196,7 +196,7 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) {
unsigned long totalInternal = 0;
unsigned long totalLeaves = 0;
NodeToOctreeSceneStats* sceneStats = Application::getInstance()->getOcteeSceneStats();
NodeToOctreeSceneStats* sceneStats = qApp->getOcteeSceneStats();
sceneStats->withReadLock([&] {
for (NodeToOctreeSceneStatsIterator i = sceneStats->begin(); i != sceneStats->end(); i++) {
//const QUuid& uuid = i->first;
@ -264,7 +264,7 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) {
QString averageReadBitstreamPerPacketString = locale.toString(averageReadBitstreamPerPacket);
label = _labels[_processedPackets];
const OctreePacketProcessor& entitiesPacketProcessor = Application::getInstance()->getOctreePacketProcessor();
const OctreePacketProcessor& entitiesPacketProcessor = qApp->getOctreePacketProcessor();
auto incomingPPS = entitiesPacketProcessor.getIncomingPPS();
auto processedPPS = entitiesPacketProcessor.getProcessedPPS();
@ -351,7 +351,7 @@ void OctreeStatsDialog::showAllOctreeServers() {
int serverCount = 0;
showOctreeServersOfType(serverCount, NodeType::EntityServer, "Entity",
Application::getInstance()->getEntityServerJurisdictions());
qApp->getEntityServerJurisdictions());
if (_octreeServerLabelsCount > serverCount) {
for (int i = serverCount; i < _octreeServerLabelsCount; i++) {
@ -427,7 +427,7 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
// now lookup stats details for this server...
if (_extraServerDetails[serverCount-1] != LESS) {
NodeToOctreeSceneStats* sceneStats = Application::getInstance()->getOcteeSceneStats();
NodeToOctreeSceneStats* sceneStats = qApp->getOcteeSceneStats();
sceneStats->withReadLock([&] {
if (sceneStats->find(nodeUUID) != sceneStats->end()) {
OctreeSceneStats& stats = sceneStats->at(nodeUUID);

View file

@ -8,10 +8,11 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "Application.h"
#include "InterfaceLogging.h"
#include "avatar/AvatarManager.h"
#include <OffscreenUi.h>
#include "Application.h"
#include "avatar/AvatarManager.h"
#include "InterfaceLogging.h"
#include "OverlayConductor.h"
OverlayConductor::OverlayConductor() {

View file

@ -45,14 +45,14 @@ PreferencesDialog::PreferencesDialog(QWidget* parent) :
connect(ui.buttonBrowseLocation, &QPushButton::clicked, this, &PreferencesDialog::openSnapshotLocationBrowser);
connect(ui.buttonBrowseScriptsLocation, &QPushButton::clicked, this, &PreferencesDialog::openScriptsLocationBrowser);
connect(ui.buttonReloadDefaultScripts, &QPushButton::clicked, Application::getInstance(), &Application::loadDefaultScripts);
connect(ui.buttonReloadDefaultScripts, &QPushButton::clicked, qApp, &Application::loadDefaultScripts);
connect(ui.buttonChangeAppearance, &QPushButton::clicked, this, &PreferencesDialog::openFullAvatarModelBrowser);
connect(ui.appearanceDescription, &QLineEdit::textChanged, this, [this](const QString& url) {
DependencyManager::get<AvatarManager>()->getMyAvatar()->useFullAvatarURL(url, "");
this->fullAvatarURLChanged(url, "");
});
connect(Application::getInstance(), &Application::fullAvatarURLChanged, this, &PreferencesDialog::fullAvatarURLChanged);
connect(qApp, &Application::fullAvatarURLChanged, this, &PreferencesDialog::fullAvatarURLChanged);
// move dialog to left side
move(parentWidget()->geometry().topLeft());
@ -183,7 +183,7 @@ void PreferencesDialog::loadPreferences() {
ui.outputStarveDetectionThresholdSpinner->setValue(audio->getOutputStarveDetectionThreshold());
ui.outputStarveDetectionPeriodSpinner->setValue(audio->getOutputStarveDetectionPeriod());
ui.realWorldFieldOfViewSpin->setValue(DependencyManager::get<AvatarManager>()->getMyAvatar()->getRealWorldFieldOfView());
ui.realWorldFieldOfViewSpin->setValue(myAvatar->getRealWorldFieldOfView());
ui.fieldOfViewSpin->setValue(qApp->getFieldOfView());
@ -200,9 +200,6 @@ void PreferencesDialog::loadPreferences() {
ui.sixenseReticleMoveSpeedSpin->setValue(InputDevice::getReticleMoveSpeed());
SixenseManager& sixense = SixenseManager::getInstance();
ui.invertSixenseButtonsCheckBox->setChecked(sixense.getInvertButtons());
// LOD items
auto lodManager = DependencyManager::get<LODManager>();
ui.desktopMinimumFPSSpin->setValue(lodManager->getDesktopLODDecreaseFPS());
@ -258,7 +255,7 @@ void PreferencesDialog::savePreferences() {
}
}
DependencyManager::get<AvatarManager>()->getMyAvatar()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value());
myAvatar->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value());
qApp->setFieldOfView(ui.fieldOfViewSpin->value());
@ -276,9 +273,7 @@ void PreferencesDialog::savePreferences() {
qApp->getApplicationCompositor().setHmdUIAngularSize(ui.oculusUIAngularSizeSpin->value());
SixenseManager& sixense = SixenseManager::getInstance();
InputDevice::setReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value());
sixense.setInvertButtons(ui.invertSixenseButtonsCheckBox->isChecked());
auto audio = DependencyManager::get<AudioClient>();
MixedProcessedAudioStream& stream = audio->getReceivedAudioStream();
@ -298,7 +293,7 @@ void PreferencesDialog::savePreferences() {
audio->setOutputStarveDetectionThreshold(ui.outputStarveDetectionThresholdSpinner->value());
audio->setOutputStarveDetectionPeriod(ui.outputStarveDetectionPeriodSpinner->value());
Application::getInstance()->resizeGL();
qApp->resizeGL();
// LOD items
auto lodManager = DependencyManager::get<LODManager>();

View file

@ -57,15 +57,15 @@ RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) :
connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &RunningScriptsWidget::updateFileFilter);
connect(ui->scriptTreeView, &QTreeView::doubleClicked, this, &RunningScriptsWidget::loadScriptFromList);
connect(ui->reloadAllButton, &QPushButton::clicked, Application::getInstance(), &Application::reloadAllScripts);
connect(ui->reloadAllButton, &QPushButton::clicked, qApp, &Application::reloadAllScripts);
connect(ui->stopAllButton, &QPushButton::clicked, this, &RunningScriptsWidget::allScriptsStopped);
connect(ui->loadScriptFromDiskButton, &QPushButton::clicked, Application::getInstance(), &Application::loadDialog);
connect(ui->loadScriptFromURLButton, &QPushButton::clicked, Application::getInstance(), &Application::loadScriptURLDialog);
connect(ui->loadScriptFromDiskButton, &QPushButton::clicked, qApp, &Application::loadDialog);
connect(ui->loadScriptFromURLButton, &QPushButton::clicked, qApp, &Application::loadScriptURLDialog);
connect(&_reloadSignalMapper, static_cast<void(QSignalMapper::*)(const QString&)>(&QSignalMapper::mapped),
Application::getInstance(), &Application::reloadOneScript);
qApp, &Application::reloadOneScript);
connect(&_stopSignalMapper, static_cast<void(QSignalMapper::*)(const QString&)>(&QSignalMapper::mapped),
[](const QString& script) { Application::getInstance()->stopScript(script); });
[](const QString& script) { qApp->stopScript(script); });
UIUtil::scaleWidgetFontSizes(this);
}
@ -83,7 +83,7 @@ void RunningScriptsWidget::updateFileFilter(const QString& filter) {
void RunningScriptsWidget::loadScriptFromList(const QModelIndex& index) {
QVariant scriptFile = _scriptsModelFilter.data(index, ScriptsModel::ScriptPath);
Application::getInstance()->loadScript(scriptFile.toString());
qApp->loadScript(scriptFile.toString());
}
void RunningScriptsWidget::loadSelectedScript() {
@ -172,7 +172,7 @@ void RunningScriptsWidget::showEvent(QShowEvent* event) {
ui->filterLineEdit->setFocus();
}
QRect parentGeometry = Application::getInstance()->getDesirableApplicationGeometry();
QRect parentGeometry = qApp->getDesirableApplicationGeometry();
int titleBarHeight = UIUtil::getWindowTitleBarHeight(this);
int topMargin = titleBarHeight;
@ -217,13 +217,13 @@ void RunningScriptsWidget::keyPressEvent(QKeyEvent *keyEvent) {
}
void RunningScriptsWidget::allScriptsStopped() {
Application::getInstance()->stopAllScripts();
qApp->stopAllScripts();
}
QVariantList RunningScriptsWidget::getRunning() {
const int WINDOWS_DRIVE_LETTER_SIZE = 1;
QVariantList result;
foreach(const QString& runningScript, Application::getInstance()->getRunningScripts()) {
foreach(const QString& runningScript, qApp->getRunningScripts()) {
QUrl runningScriptURL = QUrl(runningScript);
if (runningScriptURL.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) {
runningScriptURL = QUrl::fromLocalFile(runningScriptURL.toDisplayString(QUrl::FormattingOptions(QUrl::FullyEncoded)));
@ -245,7 +245,7 @@ QVariantList RunningScriptsWidget::getPublic() {
QVariantList RunningScriptsWidget::getPublicChildNodes(TreeNodeFolder* parent) {
QVariantList result;
QList<TreeNodeBase*> treeNodes = Application::getInstance()->getRunningScriptsWidget()->getScriptsModel()
QList<TreeNodeBase*> treeNodes = qApp->getRunningScriptsWidget()->getScriptsModel()
->getFolderNodes(parent);
for (int i = 0; i < treeNodes.size(); i++) {
TreeNodeBase* node = treeNodes.at(i);
@ -273,7 +273,7 @@ QVariantList RunningScriptsWidget::getPublicChildNodes(TreeNodeFolder* parent) {
QVariantList RunningScriptsWidget::getLocal() {
QVariantList result;
QList<TreeNodeBase*> treeNodes = Application::getInstance()->getRunningScriptsWidget()->getScriptsModel()
QList<TreeNodeBase*> treeNodes = qApp->getRunningScriptsWidget()->getScriptsModel()
->getFolderNodes(NULL);
for (int i = 0; i < treeNodes.size(); i++) {
TreeNodeBase* node = treeNodes.at(i);
@ -293,14 +293,14 @@ QVariantList RunningScriptsWidget::getLocal() {
}
bool RunningScriptsWidget::stopScriptByName(const QString& name) {
foreach (const QString& runningScript, Application::getInstance()->getRunningScripts()) {
foreach (const QString& runningScript, qApp->getRunningScripts()) {
if (QUrl(runningScript).fileName().toLower() == name.trimmed().toLower()) {
return Application::getInstance()->stopScript(runningScript, false);
return qApp->stopScript(runningScript, false);
}
}
return false;
}
bool RunningScriptsWidget::stopScript(const QString& name, bool restart) {
return Application::getInstance()->stopScript(name, restart);
return qApp->stopScript(name, restart);
}

View file

@ -10,8 +10,11 @@
//
#include "ScriptEditBox.h"
#include <QPainter>
#include <QTextBlock>
#include "ScriptLineNumberArea.h"
#include "Application.h"
ScriptEditBox::ScriptEditBox(QWidget* parent) :
QPlainTextEdit(parent)

View file

@ -98,7 +98,7 @@ bool ScriptEditorWidget::setRunning(bool run) {
if (run) {
const QString& scriptURLString = QUrl(_currentScript).toString();
// Reload script so that an out of date copy is not retrieved from the cache
_scriptEngine = Application::getInstance()->loadScript(scriptURLString, true, true, false, true);
_scriptEngine = qApp->loadScript(scriptURLString, true, true, false, true);
connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError);
connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint);
@ -106,7 +106,7 @@ bool ScriptEditorWidget::setRunning(bool run) {
connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
} else {
connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
Application::getInstance()->stopScript(_currentScript);
qApp->stopScript(_currentScript);
_scriptEngine = NULL;
}
return true;
@ -170,7 +170,7 @@ void ScriptEditorWidget::loadFile(const QString& scriptPath) {
}
const QString& scriptURLString = QUrl(_currentScript).toString();
_scriptEngine = Application::getInstance()->getScriptEngine(scriptURLString);
_scriptEngine = qApp->getScriptEngine(scriptURLString);
if (_scriptEngine != NULL) {
connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError);
@ -186,10 +186,10 @@ bool ScriptEditorWidget::save() {
bool ScriptEditorWidget::saveAs() {
QString fileName = QFileDialog::getSaveFileName(this, tr("Save script"),
Application::getInstance()->getPreviousScriptLocation(),
qApp->getPreviousScriptLocation(),
tr("JavaScript Files (*.js)"));
if (!fileName.isEmpty()) {
Application::getInstance()->setPreviousScriptLocation(fileName);
qApp->setPreviousScriptLocation(fileName);
return saveFile(fileName);
} else {
return false;

View file

@ -90,10 +90,10 @@ void ScriptEditorWindow::loadScriptMenu(const QString& scriptName) {
void ScriptEditorWindow::loadScriptClicked() {
QString scriptName = QFileDialog::getOpenFileName(this, tr("Interface"),
Application::getInstance()->getPreviousScriptLocation(),
qApp->getPreviousScriptLocation(),
tr("JavaScript Files (*.js)"));
if (!scriptName.isEmpty()) {
Application::getInstance()->setPreviousScriptLocation(scriptName);
qApp->setPreviousScriptLocation(scriptName);
addScriptEditorWidget("loading...")->loadFile(scriptName);
updateButtons();
}
@ -101,7 +101,7 @@ void ScriptEditorWindow::loadScriptClicked() {
void ScriptEditorWindow::loadMenuAboutToShow() {
_loadMenu->clear();
QStringList runningScripts = Application::getInstance()->getRunningScripts();
QStringList runningScripts = qApp->getRunningScripts();
if (runningScripts.count() > 0) {
QSignalMapper* signalMapper = new QSignalMapper(this);
foreach (const QString& runningScript, runningScripts) {

View file

@ -11,7 +11,7 @@
#include "ScriptLineNumberArea.h"
#include "Application.h"
#include "ScriptEditBox.h"
ScriptLineNumberArea::ScriptLineNumberArea(ScriptEditBox* scriptEditBox) :
QWidget(scriptEditBox)

View file

@ -13,7 +13,8 @@
#define hifi_ScriptLineNumberArea_h
#include <QWidget>
#include "ScriptEditBox.h"
class ScriptEditBox;
class ScriptLineNumberArea : public QWidget {

View file

@ -18,8 +18,10 @@
#include <avatar/AvatarManager.h>
#include <Application.h>
#include <AudioClient.h>
#include <GeometryCache.h>
#include <LODManager.h>
#include <OffscreenUi.h>
#include <PerfStat.h>
#include "BandwidthRecorder.h"
@ -115,7 +117,7 @@ void Stats::updateStats(bool force) {
STAT_UPDATE(avatarCount, avatarManager->size() - 1);
STAT_UPDATE(serverCount, nodeList->size());
STAT_UPDATE(framerate, (int)qApp->getFps());
STAT_UPDATE(simrate, (int)Application::getInstance()->getAverageSimsPerSecond());
STAT_UPDATE(simrate, (int)qApp->getAverageSimsPerSecond());
STAT_UPDATE(avatarSimrate, (int)qApp->getAvatarSimrate());
auto bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
@ -165,15 +167,15 @@ void Stats::updateStats(bool force) {
if (_expanded || force) {
SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer);
if (avatarMixer) {
STAT_UPDATE(avatarMixerKbps, roundf(
bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AvatarMixer) +
bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AvatarMixer)));
STAT_UPDATE(avatarMixerPps, roundf(
bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AvatarMixer) +
bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AvatarMixer)));
STAT_UPDATE(avatarMixerInKbps, roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AvatarMixer)));
STAT_UPDATE(avatarMixerInPps, roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AvatarMixer)));
STAT_UPDATE(avatarMixerOutKbps, roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AvatarMixer)));
STAT_UPDATE(avatarMixerOutPps, roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AvatarMixer)));
} else {
STAT_UPDATE(avatarMixerKbps, -1);
STAT_UPDATE(avatarMixerPps, -1);
STAT_UPDATE(avatarMixerInKbps, -1);
STAT_UPDATE(avatarMixerInPps, -1);
STAT_UPDATE(avatarMixerOutKbps, -1);
STAT_UPDATE(avatarMixerOutPps, -1);
}
SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer);
if (audioMixerNode || force) {
@ -207,7 +209,7 @@ void Stats::updateStats(bool force) {
unsigned long totalLeaves = 0;
std::stringstream sendingModeStream("");
sendingModeStream << "[";
NodeToOctreeSceneStats* octreeServerSceneStats = Application::getInstance()->getOcteeSceneStats();
NodeToOctreeSceneStats* octreeServerSceneStats = qApp->getOcteeSceneStats();
for (NodeToOctreeSceneStatsIterator i = octreeServerSceneStats->begin(); i != octreeServerSceneStats->end(); i++) {
//const QUuid& uuid = i->first;
OctreeSceneStats& stats = i->second;

View file

@ -47,8 +47,10 @@ class Stats : public QQuickItem {
STATS_PROPERTY(QVector3D, position, QVector3D(0, 0, 0) )
STATS_PROPERTY(float, velocity, 0)
STATS_PROPERTY(float, yaw, 0)
STATS_PROPERTY(int, avatarMixerKbps, 0)
STATS_PROPERTY(int, avatarMixerPps, 0)
STATS_PROPERTY(int, avatarMixerInKbps, 0)
STATS_PROPERTY(int, avatarMixerInPps, 0)
STATS_PROPERTY(int, avatarMixerOutKbps, 0)
STATS_PROPERTY(int, avatarMixerOutPps, 0)
STATS_PROPERTY(int, audioMixerKbps, 0)
STATS_PROPERTY(int, audioMixerPps, 0)
STATS_PROPERTY(int, downloads, 0)
@ -122,8 +124,10 @@ signals:
void positionChanged();
void velocityChanged();
void yawChanged();
void avatarMixerKbpsChanged();
void avatarMixerPpsChanged();
void avatarMixerInKbpsChanged();
void avatarMixerInPpsChanged();
void avatarMixerOutKbpsChanged();
void avatarMixerOutPpsChanged();
void audioMixerKbpsChanged();
void audioMixerPpsChanged();
void downloadsChanged();

View file

@ -25,7 +25,7 @@ ToolWindow::ToolWindow(QWidget* parent) :
# ifndef Q_OS_LINUX
setDockOptions(QMainWindow::ForceTabbedDocks);
# endif
Application::getInstance()->installEventFilter(this);
qApp->installEventFilter(this);
}
bool ToolWindow::event(QEvent* event) {
@ -34,7 +34,7 @@ bool ToolWindow::event(QEvent* event) {
if (!_hasShown) {
_hasShown = true;
QMainWindow* mainWindow = Application::getInstance()->getWindow();
QMainWindow* mainWindow = qApp->getWindow();
QRect mainGeometry = mainWindow->geometry();
int titleBarHeight = UIUtil::getWindowTitleBarHeight(this);
@ -57,7 +57,7 @@ bool ToolWindow::eventFilter(QObject* sender, QEvent* event) {
# ifndef Q_OS_LINUX
switch (event->type()) {
case QEvent::WindowStateChange:
if (Application::getInstance()->getWindow()->isMinimized()) {
if (qApp->getWindow()->isMinimized()) {
// If we are already visible, we are self-hiding
_selfHidden = isVisible();
setVisible(false);

View file

@ -10,7 +10,6 @@
//
#include "Billboard3DOverlay.h"
#include "Application.h"
Billboard3DOverlay::Billboard3DOverlay(const Billboard3DOverlay* billboard3DOverlay) :
Planar3DOverlay(billboard3DOverlay),

View file

@ -12,6 +12,7 @@
#include "Billboardable.h"
#include <Application.h>
#include <Transform.h>
void Billboardable::setProperties(const QScriptValue &properties) {
QScriptValue isFacingAvatar = properties.property("isFacingAvatar");
@ -30,7 +31,7 @@ QScriptValue Billboardable::getProperty(QScriptEngine* scriptEngine, const QStri
void Billboardable::pointTransformAtCamera(Transform& transform, glm::quat offsetRotation) {
if (isFacingAvatar()) {
glm::vec3 billboardPos = transform.getTranslation();
glm::vec3 cameraPos = Application::getInstance()->getCamera()->getPosition();
glm::vec3 cameraPos = qApp->getCamera()->getPosition();
glm::vec3 look = cameraPos - billboardPos;
float elevation = -asinf(look.y / glm::length(look));
float azimuth = atan2f(look.x, look.z);

View file

@ -13,9 +13,12 @@
#define hifi_Billboardable_h
#include <QScriptValue>
#include <QScriptEngine>
#include <Transform.h>
#include <glm/gtc/quaternion.hpp>
class QScriptEngine;
class QString;
class Transform;
class Billboardable {
public:

View file

@ -18,8 +18,8 @@
#include <DependencyManager.h>
#include <GeometryCache.h>
#include <gpu/Batch.h>
#include <RegisteredMetaTypes.h>
#include "Application.h"
#include "GeometryUtil.h"

View file

@ -71,7 +71,7 @@ void ModelOverlay::render(RenderArgs* args) {
// check to see if when we added our model to the scene they were ready, if they were not ready, then
// fix them up in the scene
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
render::PendingChanges pendingChanges;
if (_model.needsFixupInScene()) {
_model.removeFromScene(scene, pendingChanges);

View file

@ -18,7 +18,6 @@
#include "avatar/AvatarManager.h"
#include "avatar/MyAvatar.h"
#include "Application.h"
#include "Base3DOverlay.h"
PropertyBinding::PropertyBinding(QString avatar, QUuid entity) :

View file

@ -10,10 +10,11 @@
#include "Overlays.h"
#include <QtScript/QScriptValueIterator>
#include <limits>
#include <QtScript/QScriptValueIterator>
#include <OffscreenUi.h>
#include <render/Scene.h>
#include <RegisteredMetaTypes.h>
@ -76,7 +77,7 @@ void Overlays::update(float deltatime) {
void Overlays::cleanupOverlaysToDelete() {
if (!_overlaysToDelete.isEmpty()) {
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
render::PendingChanges pendingChanges;
{
@ -169,7 +170,7 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope
} else if (type == Grid3DOverlay::TYPE) {
thisOverlay = std::make_shared<Grid3DOverlay>();
} else if (type == LocalModelsOverlay::TYPE) {
thisOverlay = std::make_shared<LocalModelsOverlay>(Application::getInstance()->getEntityClipboardRenderer());
thisOverlay = std::make_shared<LocalModelsOverlay>(qApp->getEntityClipboardRenderer());
} else if (type == ModelOverlay::TYPE) {
thisOverlay = std::make_shared<ModelOverlay>();
} else if (type == Web3DOverlay::TYPE) {
@ -196,7 +197,7 @@ unsigned int Overlays::addOverlay(Overlay::Pointer overlay) {
} else {
_overlaysWorld[thisID] = overlay;
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::ScenePointer scene = qApp->getMain3DScene();
render::PendingChanges pendingChanges;
overlay->addToScene(overlay, scene, pendingChanges);

View file

@ -13,8 +13,8 @@
#include <limits>
#include <typeinfo>
#include <Application.h>
#include <avatar/AvatarManager.h>
#include <avatar/MyAvatar.h>
#include <LODManager.h>
#include <render/Scene.h>

Some files were not shown because too many files have changed in this diff Show more