Merge branch 'master' of https://github.com/highfidelity/hifi into orange

This commit is contained in:
samcake 2016-02-19 19:50:02 -08:00
commit 9b2a90b430
15 changed files with 290 additions and 123 deletions

View file

@ -0,0 +1,94 @@
//
// injectorLoadTest.js
// audio
//
// Created by Eric Levin 2/1/2016
// Copyright 2016 High Fidelity, Inc.
// This script tests what happens when many audio injectors are created and played
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
Script.include("../libraries/utils.js");
var numSoundsToPlayPerBatch = 35 // Number of simultaneously playing sounds
var numSoundsPlaying = 0;
var timeBetweenBatch = 30000;
// A green box represents an injector that is playing
var basePosition = {
x: 0,
y: 0,
z: 0
};
var soundBoxes = [];
var testSound = SoundCache.getSound("https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/dove.wav");
var totalInjectors = 0;
var clipDuration;
if(!testSound.downloaded) {
print("SOUND IS NOT READY YET")
testSound.ready.connect(function() {
playSounds();
clipDuration = testSound.duration;
});
} else {
// otherwise play sounds right away
playSounds();
clipDuration = testSound.duration;
}
function playSounds() {
print("PLAY SOUNDS!")
for (var i = 0; i < numSoundsToPlayPerBatch; i++) {
playSound();
}
Script.setTimeout(function() {
numSoundsPlaying = 0;
}, clipDuration);
print("EBL Total Number of Injectors: " + totalInjectors);
Script.setTimeout(function() {
playSounds();
}, timeBetweenBatch);
}
function playSound() {
var position = Vec3.sum(basePosition, {x: randFloat(-.1, .1), y: randFloat(-1, 1), z: randFloat(-3, -.1)});
var injector = Audio.playSound(testSound, {
position: position,
volume: 0.2
});
numSoundsPlaying++;
print("NUM SOUNDS PLAYING: " + numSoundsPlaying);
print("*******************************************");
print("INJECTOR VALUE: ")
print(JSON.stringify(injector));
totalInjectors++;
var soundBox = Entities.addEntity({
type: "Box",
name: "Debug Sound Box",
color: {red: 200, green: 10, blue: 200},
dimensions: {x: 0.1, y: 0.1, z: 0.1},
position: position
});
soundBoxes.push(soundBox);
}
function cleanup() {
soundBoxes.forEach( function(soundBox) {
Entities.deleteEntity(soundBox);
});
}
Script.scriptEnding.connect(cleanup);

View file

@ -14,9 +14,6 @@ Render.RenderShadowTask.enabled = true;
var RDT = Render.RenderDeferredTask;
RDT.AmbientOcclusion.enabled = true;
RDT.DebugDeferredBuffer.enabled = false;
["DrawOpaqueDeferred", "DrawTransparentDeferred", "DrawOverlay3DOpaque", "DrawOverlay3DTransparent"]
.map(function(name) { return RDT[name]; })
.forEach(function(job) { job.maxDrawn = job.numDrawn; });
// Set up the qml ui
var qml = Script.resolvePath('main.qml');
@ -39,4 +36,4 @@ function setDebugBufferSize(x) {
Render.RenderDeferredTask.DebugDeferredBuffer.size = {x: x, y: -1, z: 1, w: 1};
}
Script.scriptEnding.connect(function() { Render.fromJSON(oldConfig); } );
Script.scriptEnding.connect(function() { Render.load(oldConfig); } );

View file

@ -12,98 +12,109 @@ import QtQuick 2.5
import QtQuick.Controls 1.4
Column {
spacing: 8
Repeater {
model: [ "Opaque:DrawOpaqueDeferred", "Transparent:DrawTransparentDeferred",
"Opaque Overlays:DrawOverlay3DOpaque", "Transparent Overlays:DrawOverlay3DTransparent" ]
ConfigSlider {
label: qsTr(modelData.split(":")[0])
integral: true
config: Render.getConfig(modelData.split(":")[1])
property: "maxDrawn"
max: config.numDrawn
}
}
Row {
CheckBox {
text: qsTr("Display Status")
onCheckedChanged: { Render.getConfig("DrawStatus").showDisplay = checked }
}
CheckBox {
text: qsTr("Network/Physics Status")
onCheckedChanged: { Render.getConfig("DrawStatus").showNetwork = checked }
}
}
ConfigSlider {
label: qsTr("Tone Mapping Exposure")
config: Render.getConfig("ToneMapping")
property: "exposure"
min: -10; max: 10
id: root
spacing: 16
Switch {
checked: true
onClicked: ui.visible = checked
}
Column {
id: ambientOcclusion
property var config: Render.getConfig("AmbientOcclusion")
id: ui
spacing: 8
Label { text: qsTr("Ambient Occlusion") }
// TODO: Add gpuTimer
CheckBox { text: qsTr("Dithering"); checked: ambientOcclusion.config.ditheringEnabled }
Repeater {
model: [
"Resolution Level:resolutionLevel:4",
"Obscurance Level:obscuranceLevel:1",
"Radius:radius:2",
"Falloff Bias:falloffBias:0.2",
"Edge Sharpness:edgeSharpness:1",
"Blur Radius:blurRadius:6",
"Blur Deviation:blurDeviation:3"
]
ConfigSlider {
label: qsTr(modelData.split(":")[0])
config: ambientOcclusion.config
property: modelData.split(":")[1]
max: modelData.split(":")[2]
}
}
Repeater {
model: [
"Samples:numSamples:32",
"Spiral Turns:numSpiralTurns:30:"
]
model: [ "Opaque:DrawOpaqueDeferred", "Transparent:DrawTransparentDeferred",
"Opaque Overlays:DrawOverlay3DOpaque", "Transparent Overlays:DrawOverlay3DTransparent" ]
ConfigSlider {
label: qsTr(modelData.split(":")[0])
integral: true
config: ambientOcclusion.config
property: modelData.split(":")[1]
max: modelData.split(":")[2]
config: Render.getConfig(modelData.split(":")[1])
property: "maxDrawn"
max: config.numDrawn
min: -1
}
}
}
Column {
id: debug
property var config: Render.getConfig("DebugDeferredBuffer")
function setDebugMode(mode) {
debug.config.enabled = (mode != 0);
debug.config.mode = mode;
Row {
CheckBox {
text: qsTr("Display Status")
onCheckedChanged: { Render.getConfig("DrawStatus").showDisplay = checked }
}
CheckBox {
text: qsTr("Network/Physics Status")
onCheckedChanged: { Render.getConfig("DrawStatus").showNetwork = checked }
}
}
Label { text: qsTr("Debug Buffer") }
ExclusiveGroup { id: bufferGroup }
Repeater {
model: [
"Off", "Diffuse", "Metallic", "Roughness", "Normal", "Depth",
"Lighting", "Shadow", "Pyramid Depth", "Ambient Occlusion", "Custom Shader"
]
RadioButton {
text: qsTr(modelData)
exclusiveGroup: bufferGroup
checked: index == 0
onCheckedChanged: if (checked) debug.setDebugMode(index);
ConfigSlider {
label: qsTr("Tone Mapping Exposure")
config: Render.getConfig("ToneMapping")
property: "exposure"
min: -10; max: 10
}
Column {
id: ambientOcclusion
property var config: Render.getConfig("AmbientOcclusion")
Label { text: qsTr("Ambient Occlusion") }
// TODO: Add gpuTimer
CheckBox { text: qsTr("Dithering"); checked: ambientOcclusion.config.ditheringEnabled }
Repeater {
model: [
"Resolution Level:resolutionLevel:4",
"Obscurance Level:obscuranceLevel:1",
"Radius:radius:2",
"Falloff Bias:falloffBias:0.2",
"Edge Sharpness:edgeSharpness:1",
"Blur Radius:blurRadius:6",
"Blur Deviation:blurDeviation:3"
]
ConfigSlider {
label: qsTr(modelData.split(":")[0])
config: ambientOcclusion.config
property: modelData.split(":")[1]
max: modelData.split(":")[2]
}
}
Repeater {
model: [
"Samples:numSamples:32",
"Spiral Turns:numSpiralTurns:30:"
]
ConfigSlider {
label: qsTr(modelData.split(":")[0])
integral: true
config: ambientOcclusion.config
property: modelData.split(":")[1]
max: modelData.split(":")[2]
}
}
}
Column {
id: debug
property var config: Render.getConfig("DebugDeferredBuffer")
function setDebugMode(mode) {
debug.config.enabled = (mode != 0);
debug.config.mode = mode;
}
Label { text: qsTr("Debug Buffer") }
ExclusiveGroup { id: bufferGroup }
Repeater {
model: [
"Off", "Diffuse", "Metallic", "Roughness", "Normal", "Depth",
"Lighting", "Shadow", "Pyramid Depth", "Ambient Occlusion", "Custom Shader"
]
RadioButton {
text: qsTr(modelData)
exclusiveGroup: bufferGroup
checked: index == 0
onCheckedChanged: if (checked && index > 0) debug.setDebugMode(index - 1);
}
}
}
}

View file

@ -14,7 +14,8 @@ Window {
destroyOnInvisible: true
width: 800
height: 600
property alias webView: webview
Component.onCompleted: {
visible = true
addressBar.text = webview.url
@ -28,6 +29,7 @@ Window {
}
Item {
id:item
anchors.fill: parent
Rectangle {
anchors.left: parent.left
@ -125,12 +127,10 @@ Window {
console.log("New icon: " + icon)
}
profile: WebEngineProfile {
id: webviewProfile
storageName: "qmlUserBrowser"
}
profile: desktop.browserProfile
}
} // item
Keys.onPressed: {

View file

@ -11,6 +11,7 @@ WebEngineView {
root.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) {
console.log("Web Window JS message: " + sourceID + " " + lineNumber + " " + message);
});
}
// FIXME hack to get the URL with the auth token included. Remove when we move to Qt 5.6
@ -36,6 +37,10 @@ WebEngineView {
}
}
onFeaturePermissionRequested: {
grantFeaturePermission(securityOrigin, feature, true);
}
onLoadingChanged: {
// Required to support clicking on "hifi://" links
if (WebEngineView.LoadStartedStatus == loadRequest.status) {
@ -48,9 +53,12 @@ WebEngineView {
}
}
profile: WebEngineProfile {
id: webviewProfile
httpUserAgent: "Mozilla/5.0 (HighFidelityInterface)"
storageName: "qmlWebEngine"
onNewViewRequested:{
var component = Qt.createComponent("../Browser.qml");
var newWindow = component.createObject(desktop);
request.openIn(newWindow.webView)
}
profile: desktop.browserProfile
}

View file

@ -9,7 +9,7 @@ Desktop {
id: desktop
Component.onCompleted: {
WebEngine.settings.javascriptCanOpenWindows = false;
WebEngine.settings.javascriptCanOpenWindows = true;
WebEngine.settings.javascriptCanAccessClipboard = false;
WebEngine.settings.spatialNavigationEnabled = true;
WebEngine.settings.localContentCanAccessRemoteUrls = true;
@ -19,6 +19,12 @@ Desktop {
property alias toolWindow: toolWindow
ToolWindow { id: toolWindow }
property var browserProfile: WebEngineProfile {
id: webviewProfile
httpUserAgent: "Chrome/48.0 (HighFidelityInterface)"
storageName: "qmlWebEngine"
}
Action {
text: "Open Browser"
shortcut: "Ctrl+B"

View file

@ -421,8 +421,8 @@ private:
AtRestDetector _hmdAtRestDetector;
bool _lastIsMoving { false };
bool _hoverReferenceCameraFacingIsCaptured { false };
glm::vec3 _hoverReferenceCameraFacing; // hmd sensor space
glm::vec3 _hoverReferenceCameraFacing { 0.0f, 0.0f, -1.0f }; // hmd sensor space
float AVATAR_MOVEMENT_ENERGY_CONSTANT { 0.001f };
float AUDIO_ENERGY_CONSTANT { 0.000001f };
float MAX_AVATAR_MOVEMENT_PER_FRAME { 30.0f };

View file

@ -144,6 +144,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
} else {
handParams.isRightEnabled = false;
}
handParams.bodyCapsuleRadius = myAvatar->getCharacterController()->getCapsuleRadius();
_rig->updateFromHandParameters(handParams, deltaTime);

View file

@ -670,7 +670,7 @@ void AnimInverseKinematics::initConstraints() {
stConstraint->setTwistLimits(-MAX_SHOULDER_TWIST, MAX_SHOULDER_TWIST);
std::vector<float> minDots;
const float MAX_SHOULDER_SWING = PI / 20.0f;
const float MAX_SHOULDER_SWING = PI / 6.0f;
minDots.push_back(cosf(MAX_SHOULDER_SWING));
stConstraint->setSwingLimits(minDots);

View file

@ -1080,8 +1080,31 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm
void Rig::updateFromHandParameters(const HandParameters& params, float dt) {
if (_animSkeleton && _animNode) {
const float HAND_RADIUS = 0.05f;
const float BODY_RADIUS = params.bodyCapsuleRadius;
const float MIN_LENGTH = 1.0e-4f;
// project the hips onto the xz plane.
auto hipsTrans = _internalPoseSet._absolutePoses[_animSkeleton->nameToJointIndex("Hips")].trans;
const glm::vec2 bodyCircleCenter(hipsTrans.x, hipsTrans.z);
if (params.isLeftEnabled) {
_animVars.set("leftHandPosition", params.leftPosition);
// project the hand position onto the xz plane.
glm::vec2 handCircleCenter(params.leftPosition.x, params.leftPosition.z);
// check for 2d overlap of the hand and body circles.
auto circleToCircle = handCircleCenter - bodyCircleCenter;
const float circleToCircleLength = glm::length(circleToCircle);
const float penetrationDistance = HAND_RADIUS + BODY_RADIUS - circleToCircleLength;
if (penetrationDistance > 0.0f && circleToCircleLength > MIN_LENGTH) {
// push the hands out of the body
handCircleCenter += penetrationDistance * glm::normalize(circleToCircle);
}
glm::vec3 handPosition(handCircleCenter.x, params.leftPosition.y, handCircleCenter.y);
_animVars.set("leftHandPosition", handPosition);
_animVars.set("leftHandRotation", params.leftOrientation);
_animVars.set("leftHandType", (int)IKTarget::Type::RotationAndPosition);
} else {
@ -1089,8 +1112,23 @@ void Rig::updateFromHandParameters(const HandParameters& params, float dt) {
_animVars.unset("leftHandRotation");
_animVars.set("leftHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition);
}
if (params.isRightEnabled) {
_animVars.set("rightHandPosition", params.rightPosition);
// project the hand position onto the xz plane.
glm::vec2 handCircleCenter(params.rightPosition.x, params.rightPosition.z);
// check for 2d overlap of the hand and body circles.
auto circleToCircle = handCircleCenter - bodyCircleCenter;
const float circleToCircleLength = glm::length(circleToCircle);
const float penetrationDistance = HAND_RADIUS + BODY_RADIUS - circleToCircleLength;
if (penetrationDistance > 0.0f && circleToCircleLength > MIN_LENGTH) {
// push the hands out of the body
handCircleCenter += penetrationDistance * glm::normalize(circleToCircle);
}
glm::vec3 handPosition(handCircleCenter.x, params.rightPosition.y, handCircleCenter.y);
_animVars.set("rightHandPosition", handPosition);
_animVars.set("rightHandRotation", params.rightOrientation);
_animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition);
} else {

View file

@ -67,6 +67,7 @@ public:
struct HandParameters {
bool isLeftEnabled;
bool isRightEnabled;
float bodyCapsuleRadius;
glm::vec3 leftPosition = glm::vec3(); // rig space
glm::quat leftOrientation = glm::quat(); // rig space (z forward)
glm::vec3 rightPosition = glm::vec3(); // rig space

View file

@ -78,6 +78,8 @@ public:
glm::vec3 getLinearVelocity() const;
float getCapsuleRadius() const { return _radius; }
enum class State {
Ground = 0,
Takeoff,

View file

@ -45,8 +45,11 @@ ScriptAudioInjector* AudioScriptingInterface::playSound(Sound* sound, const Audi
// stereo option isn't set from script, this comes from sound metadata or filename
AudioInjectorOptions optionsCopy = injectorOptions;
optionsCopy.stereo = sound->isStereo();
return new ScriptAudioInjector(AudioInjector::playSound(sound->getByteArray(), optionsCopy, _localAudioInterface));
auto injector = AudioInjector::playSound(sound->getByteArray(), optionsCopy, _localAudioInterface);
if (!injector) {
return NULL;
}
return new ScriptAudioInjector(injector);
} else {
qCDebug(scriptengine) << "AudioScriptingInterface::playSound called with null Sound object.";

View file

@ -30,7 +30,6 @@ const QString OpenVrDisplayPlugin::NAME("OpenVR (Vive)");
const QString StandingHMDSensorMode = "Standing HMD Sensor Mode"; // this probably shouldn't be hardcoded here
static vr::IVRCompositor* _compositor{ nullptr };
static vr::TrackedDevicePose_t _presentThreadTrackedDevicePose[vr::k_unMaxTrackedDeviceCount];
vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
static mat4 _sensorResetMat;
@ -43,12 +42,12 @@ bool OpenVrDisplayPlugin::isSupported() const {
void OpenVrDisplayPlugin::activate() {
_container->setIsOptionChecked(StandingHMDSensorMode, true);
if (!_hmd) {
_hmd = acquireOpenVrSystem();
if (!_system) {
_system = acquireOpenVrSystem();
}
Q_ASSERT(_hmd);
Q_ASSERT(_system);
_hmd->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y);
_system->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y);
// Recommended render target size is per-eye, so double the X size for
// left + right eyes
_renderTargetSize.x *= 2;
@ -56,8 +55,8 @@ void OpenVrDisplayPlugin::activate() {
{
Lock lock(_poseMutex);
openvr_for_each_eye([&](vr::Hmd_Eye eye) {
_eyeOffsets[eye] = toGlm(_hmd->GetEyeToHeadTransform(eye));
_eyeProjections[eye] = toGlm(_hmd->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL));
_eyeOffsets[eye] = toGlm(_system->GetEyeToHeadTransform(eye));
_eyeProjections[eye] = toGlm(_system->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL));
});
// FIXME Calculate the proper combined projection by using GetProjectionRaw values from both eyes
_cullingProjection = _eyeProjections[0];
@ -71,9 +70,9 @@ void OpenVrDisplayPlugin::activate() {
void OpenVrDisplayPlugin::deactivate() {
_container->setIsOptionChecked(StandingHMDSensorMode, false);
if (_hmd) {
if (_system) {
releaseOpenVrSystem();
_hmd = nullptr;
_system = nullptr;
}
_compositor = nullptr;
HmdDisplayPlugin::deactivate();
@ -96,9 +95,24 @@ void OpenVrDisplayPlugin::resetSensors() {
_sensorResetMat = glm::inverse(cancelOutRollAndPitch(m));
}
glm::mat4 OpenVrDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
Lock lock(_poseMutex);
float displayFrequency = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_DisplayFrequency_Float);
float frameDuration = 1.f / displayFrequency;
float vsyncToPhotons = _system->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SecondsFromVsyncToPhotons_Float);
// TODO: this seems awfuly long, 44ms total, but it produced the best results.
const float NUM_PREDICTION_FRAMES = 3.0f;
float predictedSecondsFromNow = NUM_PREDICTION_FRAMES * frameDuration + vsyncToPhotons;
vr::TrackedDevicePose_t predictedTrackedDevicePose[vr::k_unMaxTrackedDeviceCount];
_system->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseSeated, predictedSecondsFromNow, predictedTrackedDevicePose, vr::k_unMaxTrackedDeviceCount);
// copy and process predictedTrackedDevicePoses
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
_trackedDevicePose[i] = predictedTrackedDevicePose[i];
_trackedDevicePoseMat4[i] = _sensorResetMat * toGlm(_trackedDevicePose[i].mDeviceToAbsoluteTracking);
}
return _trackedDevicePoseMat4[0];
}
@ -114,16 +128,8 @@ void OpenVrDisplayPlugin::internalPresent() {
glFinish();
_compositor->WaitGetPoses(_presentThreadTrackedDevicePose, vr::k_unMaxTrackedDeviceCount, nullptr, 0);
{
// copy and process _presentThreadTrackedDevicePoses
Lock lock(_poseMutex);
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
_trackedDevicePose[i] = _presentThreadTrackedDevicePose[i];
_trackedDevicePoseMat4[i] = _sensorResetMat * toGlm(_trackedDevicePose[i].mDeviceToAbsoluteTracking);
}
}
vr::TrackedDevicePose_t currentTrackedDevicePose[vr::k_unMaxTrackedDeviceCount];
_compositor->WaitGetPoses(currentTrackedDevicePose, vr::k_unMaxTrackedDeviceCount, nullptr, 0);
// Handle the mirroring in the base class
HmdDisplayPlugin::internalPresent();

View file

@ -35,7 +35,7 @@ protected:
virtual void internalPresent() override;
private:
vr::IVRSystem* _hmd { nullptr };
vr::IVRSystem* _system { nullptr };
static const QString NAME;
mutable Mutex _poseMutex;
};