mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 14:03:55 +02:00
merge fix
This commit is contained in:
commit
54957a2fa1
24 changed files with 339 additions and 289 deletions
50
examples/audioMuteExample.js
Normal file
50
examples/audioMuteExample.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// audioMuteExample.js
|
||||
// examples
|
||||
//
|
||||
// Created by Thijs Wenker on 10/31/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// This example shows how to use the AudioDevice mute functions.
|
||||
// Press the MUTE/UNMUTE button to see it function.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var toggleMuteButton = Overlays.addOverlay("text", {
|
||||
x: 50,
|
||||
y: 50,
|
||||
width: 190,
|
||||
height: 50,
|
||||
backgroundColor: { red: 255, green: 255, blue: 255},
|
||||
color: { red: 255, green: 0, blue: 0},
|
||||
font: {size: 30},
|
||||
topMargin: 10
|
||||
});
|
||||
|
||||
function muteButtonText() {
|
||||
print("Audio Muted: " + AudioDevice.getMuted());
|
||||
}
|
||||
|
||||
function onMuteStateChanged() {
|
||||
Overlays.editOverlay(toggleMuteButton,
|
||||
AudioDevice.getMuted() ? {text: "UNMUTE", leftMargin: 10} : {text: "MUTE", leftMargin: 38});
|
||||
print("Audio Muted: " + AudioDevice.getMuted());
|
||||
}
|
||||
|
||||
function mousePressEvent(event) {
|
||||
if (Overlays.getOverlayAtPoint({x: event.x, y: event.y}) == toggleMuteButton) {
|
||||
AudioDevice.toggleMute()
|
||||
}
|
||||
}
|
||||
|
||||
function scriptEnding() {
|
||||
Overlays.deleteOverlay(toggleMuteButton);
|
||||
}
|
||||
|
||||
onMuteStateChanged();
|
||||
|
||||
AudioDevice.muteToggled.connect(onMuteStateChanged);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
|
@ -1,167 +0,0 @@
|
|||
//
|
||||
// voxelDrumming.js
|
||||
// examples
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 2/14/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// This is an example script that demonstrates use of the Overlays, Controller, and Audio classes
|
||||
//
|
||||
// It adds Hydra controller "fingertip on voxels" drumming
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
Menu.addMenuItem({
|
||||
menuName: "Developer > Hand Options",
|
||||
menuItemName: "Voxel Drumming",
|
||||
isCheckable: true,
|
||||
isChecked: false
|
||||
});
|
||||
|
||||
var collisionCenter = new Array();
|
||||
collisionCenter[0] = { x: 0, y: 0, z: 0};
|
||||
collisionCenter[1] = { x: 0, y: 0, z: 0};
|
||||
|
||||
var collisionAge = new Array();
|
||||
collisionAge[0] = 0;
|
||||
collisionAge[1] = 0;
|
||||
|
||||
var collisionDuration = new Array();
|
||||
collisionDuration[0] = 0;
|
||||
collisionDuration[1] = 0;
|
||||
|
||||
var isColliding = new Array();
|
||||
isColliding[0] = false;
|
||||
isColliding[1] = false;
|
||||
|
||||
var highlightVoxel = Overlays.addOverlay("cube",
|
||||
{
|
||||
position: { x: 0, y: 0, z: 0},
|
||||
size: 0,
|
||||
color: { red: 0, green: 0, blue: 0 },
|
||||
visible: false,
|
||||
lineWidth: 3,
|
||||
solid: false
|
||||
});
|
||||
|
||||
var collisionBubble = new Array();
|
||||
collisionBubble[0] = Overlays.addOverlay("sphere",
|
||||
{
|
||||
position: { x: 0, y: 0, z: 0},
|
||||
size: 0,
|
||||
color: { red: 0, green: 0, blue: 0 },
|
||||
alpha: 0.5,
|
||||
visible: false
|
||||
});
|
||||
collisionBubble[1] = Overlays.addOverlay("sphere",
|
||||
{
|
||||
position: { x: 0, y: 0, z: 0},
|
||||
size: 0,
|
||||
color: { red: 0, green: 0, blue: 0 },
|
||||
alpha: 0.5,
|
||||
visible: false
|
||||
});
|
||||
|
||||
var audioOptions = new AudioInjectionOptions();
|
||||
audioOptions.position = { x: MyAvatar.position.x, y: MyAvatar.position.y + 1, z: MyAvatar.position.z };
|
||||
audioOptions.volume = 1;
|
||||
|
||||
|
||||
function clamp(valueToClamp, minValue, maxValue) {
|
||||
return Math.max(minValue, Math.min(maxValue, valueToClamp));
|
||||
}
|
||||
|
||||
function produceCollisionSound(deltaTime, palm, voxelDetail) {
|
||||
// Collision between finger and a voxel plays sound
|
||||
|
||||
var palmVelocity = Controller.getSpatialControlVelocity(palm * 2);
|
||||
var speed = Vec3.length(palmVelocity);
|
||||
var fingerTipPosition = Controller.getSpatialControlPosition(palm * 2 + 1);
|
||||
|
||||
var LOWEST_FREQUENCY = 100.0;
|
||||
var HERTZ_PER_RGB = 3.0;
|
||||
var DECAY_PER_SAMPLE = 0.0005;
|
||||
var DURATION_MAX = 2.0;
|
||||
var MIN_VOLUME = 0.1;
|
||||
var volume = MIN_VOLUME + clamp(speed, 0.0, (1.0 - MIN_VOLUME));
|
||||
var duration = volume;
|
||||
|
||||
collisionCenter[palm] = fingerTipPosition;
|
||||
collisionAge[palm] = deltaTime;
|
||||
collisionDuration[palm] = duration;
|
||||
|
||||
var voxelBrightness = voxelDetail.red + voxelDetail.green + voxelDetail.blue;
|
||||
var frequency = LOWEST_FREQUENCY + (voxelBrightness * HERTZ_PER_RGB);
|
||||
|
||||
audioOptions.position = fingerTipPosition;
|
||||
Audio.startDrumSound(volume, frequency, DURATION_MAX, DECAY_PER_SAMPLE, audioOptions);
|
||||
}
|
||||
|
||||
function update(deltaTime) {
|
||||
// Voxel Drumming with fingertips if enabled
|
||||
if (Menu.isOptionChecked("Voxel Drumming")) {
|
||||
|
||||
for (var palm = 0; palm < 2; palm++) {
|
||||
var fingerTipPosition = Controller.getSpatialControlPosition(palm * 2 + 1);
|
||||
|
||||
var voxel = Voxels.getVoxelEnclosingPoint(fingerTipPosition);
|
||||
if (voxel.s > 0) {
|
||||
if (!isColliding[palm]) {
|
||||
// Collision has just started
|
||||
isColliding[palm] = true;
|
||||
produceCollisionSound(deltaTime, palm, voxel);
|
||||
|
||||
// Set highlight voxel
|
||||
Overlays.editOverlay(highlightVoxel,
|
||||
{
|
||||
position: { x: voxel.x, y: voxel.y, z: voxel.z},
|
||||
size: voxel.s + 0.002,
|
||||
color: { red: voxel.red + 128, green: voxel.green + 128, blue: voxel.blue + 128 },
|
||||
visible: true
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (isColliding[palm]) {
|
||||
// Collision has just ended
|
||||
isColliding[palm] = false;
|
||||
Overlays.editOverlay(highlightVoxel, { visible: false });
|
||||
}
|
||||
}
|
||||
|
||||
if (collisionAge[palm] > 0) {
|
||||
collisionAge[palm] += deltaTime;
|
||||
}
|
||||
|
||||
// If hand/voxel collision has happened, render a little expanding sphere
|
||||
if (collisionAge[palm] > 0) {
|
||||
var opacity = clamp(1 - (collisionAge[palm] / collisionDuration[palm]), 0, 1);
|
||||
var size = collisionAge[palm] * 0.25;
|
||||
|
||||
Overlays.editOverlay(collisionBubble[palm],
|
||||
{
|
||||
position: { x: collisionCenter[palm].x, y: collisionCenter[palm].y, z: collisionCenter[palm].z},
|
||||
size: size,
|
||||
color: { red: 255, green: 0, blue: 0 },
|
||||
alpha: 0.5 * opacity,
|
||||
visible: true
|
||||
});
|
||||
|
||||
if (collisionAge[palm] > collisionDuration[palm]) {
|
||||
collisionAge[palm] = 0;
|
||||
Overlays.editOverlay(collisionBubble[palm], { visible: false });
|
||||
}
|
||||
}
|
||||
} // palm loop
|
||||
} // menu item check
|
||||
}
|
||||
Script.update.connect(update);
|
||||
|
||||
function scriptEnding() {
|
||||
Overlays.deleteOverlay(highlightVoxel);
|
||||
Overlays.deleteOverlay(collisionBubble[0]);
|
||||
Overlays.deleteOverlay(collisionBubble[1]);
|
||||
Menu.removeMenuItem("Developer > Hand Options","Voxel Drumming");
|
||||
}
|
||||
Script.scriptEnding.connect(scriptEnding);
|
|
@ -11,50 +11,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the radius (hard cutoff) of the light effect
|
||||
uniform float radius;
|
||||
|
||||
void main(void) {
|
||||
// find the right "right" direction
|
||||
vec3 firstRightCandidate = cross(gl_LightSource[1].spotDirection, vec3(0.0, 1.0, 0.0));
|
||||
vec3 secondRightCandidate = cross(gl_LightSource[1].spotDirection, vec3(1.0, 0.0, 0.0));
|
||||
vec3 right = mix(firstRightCandidate, secondRightCandidate, step(length(firstRightCandidate), length(secondRightCandidate)));
|
||||
right = normalize(right);
|
||||
|
||||
// and the "up"
|
||||
vec3 up = cross(right, gl_LightSource[1].spotDirection);
|
||||
|
||||
// and the "back," which depends on whether this is a spot light
|
||||
vec3 back = -gl_LightSource[1].spotDirection * step(gl_LightSource[1].spotCosCutoff, 0.0);
|
||||
|
||||
// find the eight corners of the bounds
|
||||
vec4 c0 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up - right + back), 1.0);
|
||||
vec4 c1 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up + right + back), 1.0);
|
||||
vec4 c2 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up - right + back), 1.0);
|
||||
vec4 c3 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up + right + back), 1.0);
|
||||
vec4 c4 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up - right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c5 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up + right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c6 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up - right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c7 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up + right + gl_LightSource[1].spotDirection), 1.0);
|
||||
|
||||
// find their projected extents
|
||||
vec2 extents = max(
|
||||
max(max(gl_Vertex.xy * (c0.xy / max(c0.w, 0.001)), gl_Vertex.xy * (c1.xy / max(c1.w, 0.001))),
|
||||
max(gl_Vertex.xy * (c2.xy / max(c2.w, 0.001)), gl_Vertex.xy * (c3.xy / max(c3.w, 0.001)))),
|
||||
max(max(gl_Vertex.xy * (c4.xy / max(c4.w, 0.001)), gl_Vertex.xy * (c5.xy / max(c5.w, 0.001))),
|
||||
max(gl_Vertex.xy * (c6.xy / max(c6.w, 0.001)), gl_Vertex.xy * (c7.xy / max(c7.w, 0.001)))));
|
||||
|
||||
// make sure they don't extend beyond the screen
|
||||
extents = min(extents, vec2(1.0, 1.0));
|
||||
|
||||
gl_Position = vec4(gl_Vertex.xy * extents, 0.0, 1.0);
|
||||
gl_TexCoord[0] = vec4(dot(gl_Position, gl_ObjectPlaneS[3]), dot(gl_Position, gl_ObjectPlaneT[3]), 0.0, 1.0);
|
||||
gl_Position = ftransform();
|
||||
vec4 projected = gl_Position / gl_Position.w;
|
||||
gl_TexCoord[0] = vec4(dot(projected, gl_ObjectPlaneS[3]), dot(projected, gl_ObjectPlaneT[3]), 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -39,8 +39,13 @@ uniform vec2 depthTexCoordScale;
|
|||
uniform float radius;
|
||||
|
||||
void main(void) {
|
||||
// get the depth and exit early if it doesn't pass the test
|
||||
float depth = texture2D(depthMap, gl_TexCoord[0].st).r;
|
||||
if (depth < gl_FragCoord.z) {
|
||||
discard;
|
||||
}
|
||||
// compute the view space position using the depth
|
||||
float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0);
|
||||
float z = near / (depth * depthScale - 1.0);
|
||||
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
||||
|
||||
// get the normal from the map
|
||||
|
|
|
@ -39,8 +39,13 @@ uniform vec2 depthTexCoordScale;
|
|||
uniform float radius;
|
||||
|
||||
void main(void) {
|
||||
// get the depth and exit early if it doesn't pass the test
|
||||
float depth = texture2D(depthMap, gl_TexCoord[0].st).r;
|
||||
if (depth < gl_FragCoord.z) {
|
||||
discard;
|
||||
}
|
||||
// compute the view space position using the depth
|
||||
float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0);
|
||||
float z = near / (depth * depthScale - 1.0);
|
||||
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
||||
|
||||
// get the normal from the map
|
||||
|
|
|
@ -450,6 +450,9 @@ Application::~Application() {
|
|||
_audio.thread()->quit();
|
||||
_audio.thread()->wait();
|
||||
|
||||
// kill any audio injectors that are still around
|
||||
AudioScriptingInterface::getInstance().stopAllInjectors();
|
||||
|
||||
_octreeProcessor.terminate();
|
||||
_voxelHideShowThread.terminate();
|
||||
_voxelEditSender.terminate();
|
||||
|
@ -620,8 +623,8 @@ void Application::paintGL() {
|
|||
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||
static const float THIRD_PERSON_CAMERA_DISTANCE = 1.5f;
|
||||
_myCamera.setPosition(_myAvatar->getUprightHeadPosition() +
|
||||
_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, 1.0f) * THIRD_PERSON_CAMERA_DISTANCE * _myAvatar->getScale());
|
||||
_myCamera.setPosition(_myAvatar->getDefaultEyePosition() +
|
||||
_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, 1.0f) * THIRD_PERSON_CAMERA_DISTANCE * _myAvatar->getScale());
|
||||
if (OculusManager::isConnected()) {
|
||||
_myCamera.setRotation(_myAvatar->getWorldAlignedOrientation());
|
||||
} else {
|
||||
|
@ -1980,6 +1983,9 @@ void Application::init() {
|
|||
connect(getAudio(), &Audio::preProcessOriginalInboundAudio, &_audioReflector,
|
||||
&AudioReflector::preProcessOriginalInboundAudio,Qt::DirectConnection);
|
||||
|
||||
connect(getAudio(), &Audio::muteToggled, AudioDeviceScriptingInterface::getInstance(),
|
||||
&AudioDeviceScriptingInterface::muteToggled, Qt::DirectConnection);
|
||||
|
||||
// save settings when avatar changes
|
||||
connect(_myAvatar, &MyAvatar::transformChanged, this, &Application::bumpSettings);
|
||||
}
|
||||
|
|
|
@ -1057,10 +1057,6 @@ float Avatar::getPelvisFloatingHeight() const {
|
|||
return -_skeletonModel.getBindExtents().minimum.y;
|
||||
}
|
||||
|
||||
float Avatar::getPelvisToHeadLength() const {
|
||||
return glm::distance(_position, getHead()->getPosition());
|
||||
}
|
||||
|
||||
void Avatar::setShowDisplayName(bool showDisplayName) {
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::NamesAboveHeads)) {
|
||||
_displayNameAlpha = 0.0f;
|
||||
|
|
|
@ -230,7 +230,6 @@ protected:
|
|||
float getSkeletonHeight() const;
|
||||
float getHeadHeight() const;
|
||||
float getPelvisFloatingHeight() const;
|
||||
float getPelvisToHeadLength() const;
|
||||
glm::vec3 getDisplayNamePosition();
|
||||
|
||||
void renderDisplayName();
|
||||
|
|
|
@ -416,7 +416,7 @@ void MyAvatar::renderDebugBodyPoints() {
|
|||
glPushMatrix();
|
||||
glColor4f(0, 1, 0, .5f);
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
Application::getInstance()->getGeometryCache()->renderSphere(0.2, 10, 10);
|
||||
Application::getInstance()->getGeometryCache()->renderSphere(0.2f, 10.0f, 10.0f);
|
||||
glPopMatrix();
|
||||
|
||||
// Head Sphere
|
||||
|
@ -424,7 +424,7 @@ void MyAvatar::renderDebugBodyPoints() {
|
|||
glPushMatrix();
|
||||
glColor4f(0, 1, 0, .5f);
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
Application::getInstance()->getGeometryCache()->renderSphere(0.15, 10, 10);
|
||||
Application::getInstance()->getGeometryCache()->renderSphere(0.15f, 10.0f, 10.0f);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
@ -1004,10 +1004,6 @@ bool MyAvatar::isLookingAtLeftEye() {
|
|||
return _isLookingAtLeftEye;
|
||||
}
|
||||
|
||||
glm::vec3 MyAvatar::getUprightHeadPosition() const {
|
||||
return _position + getWorldAlignedOrientation() * glm::vec3(0.0f, getPelvisToHeadLength(), 0.0f);
|
||||
}
|
||||
|
||||
glm::vec3 MyAvatar::getDefaultEyePosition() const {
|
||||
return _position + getWorldAlignedOrientation() * _skeletonModel.getDefaultEyeModelPosition();
|
||||
}
|
||||
|
|
|
@ -66,7 +66,6 @@ public:
|
|||
const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; }
|
||||
const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; }
|
||||
glm::vec3 getGravity() const { return _gravity; }
|
||||
glm::vec3 getUprightHeadPosition() const;
|
||||
glm::vec3 getDefaultEyePosition() const;
|
||||
bool getShouldRenderLocally() const { return _shouldRender; }
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ void OculusManager::connect() {
|
|||
|
||||
if (!_camera) {
|
||||
_camera = new Camera;
|
||||
configureCamera(*_camera, 0, 0); // no need to use screen dimensions; they're ignored
|
||||
}
|
||||
|
||||
if (!_programInitialized) {
|
||||
|
@ -420,7 +421,7 @@ void OculusManager::endFrameTiming() {
|
|||
//Sets the camera FoV and aspect ratio
|
||||
void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenHeight) {
|
||||
#ifdef HAVE_LIBOVR
|
||||
camera.setAspectRatio((float)_renderTargetSize.w / _renderTargetSize.h);
|
||||
camera.setAspectRatio(_renderTargetSize.w * 0.5f / _renderTargetSize.h);
|
||||
camera.setFieldOfView(atan(_eyeFov[0].UpTan) * DEGREES_PER_RADIAN * 2.0f);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -73,6 +73,12 @@ void DeferredLightingEffect::renderWireCube(float size) {
|
|||
releaseSimpleProgram();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::renderSolidCone(float base, float height, int slices, int stacks) {
|
||||
bindSimpleProgram();
|
||||
Application::getInstance()->getGeometryCache()->renderCone(base, height, slices, stacks);
|
||||
releaseSimpleProgram();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& ambient,
|
||||
const glm::vec3& diffuse, const glm::vec3& specular, float constantAttenuation,
|
||||
float linearAttenuation, float quadraticAttenuation) {
|
||||
|
@ -216,11 +222,18 @@ void DeferredLightingEffect::render() {
|
|||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f);
|
||||
glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f);
|
||||
glTexGenfv(GL_S, GL_OBJECT_PLANE, (const GLfloat*)&sCoefficients);
|
||||
glTexGenfv(GL_T, GL_OBJECT_PLANE, (const GLfloat*)&tCoefficients);
|
||||
|
||||
// enlarge the scales slightly to account for tesselation
|
||||
const float SCALE_EXPANSION = 0.1f;
|
||||
|
||||
const glm::vec3& eyePoint = Application::getInstance()->getDisplayViewFrustum()->getPosition();
|
||||
|
||||
if (!_pointLights.isEmpty()) {
|
||||
_pointLight.bind();
|
||||
_pointLight.setUniformValue(_pointLightLocations.nearLocation, nearVal);
|
||||
|
@ -238,7 +251,28 @@ void DeferredLightingEffect::render() {
|
|||
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, light.linearAttenuation);
|
||||
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, light.quadraticAttenuation);
|
||||
|
||||
renderFullscreenQuad();
|
||||
glPushMatrix();
|
||||
|
||||
float expandedRadius = light.radius * (1.0f + SCALE_EXPANSION);
|
||||
if (glm::distance(eyePoint, glm::vec3(light.position)) < expandedRadius) {
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0f, 0.0f, -1.0f);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
renderFullscreenQuad();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
} else {
|
||||
glTranslatef(light.position.x, light.position.y, light.position.z);
|
||||
Application::getInstance()->getGeometryCache()->renderSphere(expandedRadius, 64, 64);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
_pointLights.clear();
|
||||
|
||||
|
@ -265,7 +299,34 @@ void DeferredLightingEffect::render() {
|
|||
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, light.exponent);
|
||||
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, glm::degrees(light.cutoff));
|
||||
|
||||
renderFullscreenQuad();
|
||||
glPushMatrix();
|
||||
|
||||
float expandedRadius = light.radius * (1.0f + SCALE_EXPANSION);
|
||||
float edgeRadius = expandedRadius / glm::cos(light.cutoff);
|
||||
if (glm::distance(eyePoint, glm::vec3(light.position)) < edgeRadius) {
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0f, 0.0f, -1.0f);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
renderFullscreenQuad();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
} else {
|
||||
glTranslatef(light.position.x, light.position.y, light.position.z);
|
||||
glm::quat spotRotation = rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), light.direction);
|
||||
glm::vec3 axis = glm::axis(spotRotation);
|
||||
glRotatef(glm::degrees(glm::angle(spotRotation)), axis.x, axis.y, axis.z);
|
||||
glTranslatef(0.0f, 0.0f, -light.radius * (1.0f + SCALE_EXPANSION * 0.5f));
|
||||
Application::getInstance()->getGeometryCache()->renderCone(expandedRadius * glm::tan(light.cutoff),
|
||||
expandedRadius, 64, 32);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
_spotLights.clear();
|
||||
|
||||
|
@ -285,6 +346,8 @@ void DeferredLightingEffect::render() {
|
|||
|
||||
freeFBO->release();
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
// now transfer the lit region to the primary fbo
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
glColorMask(true, true, true, false);
|
||||
|
|
|
@ -47,6 +47,9 @@ public:
|
|||
|
||||
//// Renders a wireframe cube with the simple program.
|
||||
void renderWireCube(float size);
|
||||
|
||||
//// Renders a solid cone with the simple program.
|
||||
void renderSolidCone(float base, float height, int slices, int stacks);
|
||||
|
||||
/// Adds a point light to render for the current frame.
|
||||
void addPointLight(const glm::vec3& position, float radius, const glm::vec3& ambient = glm::vec3(0.0f, 0.0f, 0.0f),
|
||||
|
|
|
@ -110,15 +110,18 @@ void GeometryCache::renderHemisphere(int slices, int stacks) {
|
|||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
const int NUM_VERTICES_PER_TRIANGLE = 3;
|
||||
const int NUM_TRIANGLES_PER_QUAD = 2;
|
||||
const int NUM_VERTICES_PER_TRIANGULATED_QUAD = NUM_VERTICES_PER_TRIANGLE * NUM_TRIANGLES_PER_QUAD;
|
||||
const int NUM_COORDS_PER_VERTEX = 3;
|
||||
const int NUM_BYTES_PER_VERTEX = NUM_COORDS_PER_VERTEX * sizeof(GLfloat);
|
||||
const int NUM_BYTES_PER_INDEX = sizeof(GLushort);
|
||||
|
||||
void GeometryCache::renderSphere(float radius, int slices, int stacks) {
|
||||
VerticesIndices& vbo = _sphereVBOs[IntPair(slices, stacks)];
|
||||
int vertices = slices * (stacks - 1) + 2;
|
||||
const int NUM_VERTICES_PER_TRIANGLE = 3;
|
||||
const int NUM_TRIANGLES_PER_QUAD = 2;
|
||||
int indices = slices * NUM_TRIANGLES_PER_QUAD * NUM_VERTICES_PER_TRIANGLE * (stacks - 1) + slices * NUM_TRIANGLES_PER_QUAD * NUM_VERTICES_PER_TRIANGLE;
|
||||
if (vbo.first == 0) {
|
||||
const int NUM_COORDS_PER_VERTEX = 3;
|
||||
int vertices = slices * (stacks - 1) + 2;
|
||||
int indices = slices * stacks * NUM_VERTICES_PER_TRIANGULATED_QUAD;
|
||||
if (vbo.first == 0) {
|
||||
GLfloat* vertexData = new GLfloat[vertices * NUM_COORDS_PER_VERTEX];
|
||||
GLfloat* vertex = vertexData;
|
||||
|
||||
|
@ -148,8 +151,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks) {
|
|||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
const int BYTES_PER_VERTEX = NUM_COORDS_PER_VERTEX * sizeof(GLfloat);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
|
@ -192,8 +194,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks) {
|
|||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
const int BYTES_PER_INDEX = sizeof(GLushort);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
} else {
|
||||
|
@ -239,8 +240,7 @@ void GeometryCache::renderSquare(int xDivisions, int yDivisions) {
|
|||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
const int BYTES_PER_VERTEX = 3 * sizeof(GLfloat);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
|
@ -263,8 +263,7 @@ void GeometryCache::renderSquare(int xDivisions, int yDivisions) {
|
|||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
const int BYTES_PER_INDEX = sizeof(GLushort);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
} else {
|
||||
|
@ -313,8 +312,7 @@ void GeometryCache::renderHalfCylinder(int slices, int stacks) {
|
|||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
const int BYTES_PER_VERTEX = 3 * sizeof(GLfloat);
|
||||
glBufferData(GL_ARRAY_BUFFER, 2 * vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, 2 * vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
|
@ -337,8 +335,7 @@ void GeometryCache::renderHalfCylinder(int slices, int stacks) {
|
|||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
const int BYTES_PER_INDEX = sizeof(GLushort);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
} else {
|
||||
|
@ -360,6 +357,106 @@ void GeometryCache::renderHalfCylinder(int slices, int stacks) {
|
|||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderCone(float base, float height, int slices, int stacks) {
|
||||
VerticesIndices& vbo = _halfCylinderVBOs[IntPair(slices, stacks)];
|
||||
int vertices = (stacks + 2) * slices;
|
||||
int baseTriangles = slices - 2;
|
||||
int indices = NUM_VERTICES_PER_TRIANGULATED_QUAD * slices * stacks + NUM_VERTICES_PER_TRIANGLE * baseTriangles;
|
||||
if (vbo.first == 0) {
|
||||
GLfloat* vertexData = new GLfloat[vertices * NUM_COORDS_PER_VERTEX * 2];
|
||||
GLfloat* vertex = vertexData;
|
||||
// cap
|
||||
for (int i = 0; i < slices; i++) {
|
||||
float theta = TWO_PI * i / slices;
|
||||
|
||||
//normals
|
||||
*(vertex++) = 0.0f;
|
||||
*(vertex++) = 0.0f;
|
||||
*(vertex++) = -1.0f;
|
||||
|
||||
// vertices
|
||||
*(vertex++) = cosf(theta);
|
||||
*(vertex++) = sinf(theta);
|
||||
*(vertex++) = 0.0f;
|
||||
}
|
||||
// body
|
||||
for (int i = 0; i <= stacks; i++) {
|
||||
float z = (float)i / stacks;
|
||||
float radius = 1.0f - z;
|
||||
|
||||
for (int j = 0; j < slices; j++) {
|
||||
float theta = TWO_PI * j / slices;
|
||||
|
||||
//normals
|
||||
*(vertex++) = cosf(theta) / SQUARE_ROOT_OF_2;
|
||||
*(vertex++) = sinf(theta) / SQUARE_ROOT_OF_2;
|
||||
*(vertex++) = 1.0f / SQUARE_ROOT_OF_2;
|
||||
|
||||
// vertices
|
||||
*(vertex++) = radius * cosf(theta);
|
||||
*(vertex++) = radius * sinf(theta);
|
||||
*(vertex++) = z;
|
||||
}
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBufferData(GL_ARRAY_BUFFER, 2 * vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
GLushort* index = indexData;
|
||||
for (int i = 0; i < baseTriangles; i++) {
|
||||
*(index++) = 0;
|
||||
*(index++) = i + 1;
|
||||
*(index++) = i + 2;
|
||||
}
|
||||
for (int i = 1; i <= stacks; i++) {
|
||||
GLushort bottom = i * slices;
|
||||
GLushort top = bottom + slices;
|
||||
for (int j = 0; j < slices; j++) {
|
||||
int next = (j + 1) % slices;
|
||||
|
||||
*(index++) = bottom + j;
|
||||
*(index++) = top + next;
|
||||
*(index++) = top + j;
|
||||
|
||||
*(index++) = bottom + j;
|
||||
*(index++) = bottom + next;
|
||||
*(index++) = top + next;
|
||||
}
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
}
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
int stride = NUM_VERTICES_PER_TRIANGULATED_QUAD * sizeof(float);
|
||||
glNormalPointer(GL_FLOAT, stride, 0);
|
||||
glVertexPointer(NUM_COORDS_PER_VERTEX, GL_FLOAT, stride, (const void *)(NUM_COORDS_PER_VERTEX * sizeof(float)));
|
||||
|
||||
glPushMatrix();
|
||||
glScalef(base, base, height);
|
||||
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderGrid(int xDivisions, int yDivisions) {
|
||||
QOpenGLBuffer& buffer = _gridBuffers[IntPair(xDivisions, yDivisions)];
|
||||
int vertices = (xDivisions + 1 + yDivisions + 1) * 2;
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
void renderSphere(float radius, int slices, int stacks);
|
||||
void renderSquare(int xDivisions, int yDivisions);
|
||||
void renderHalfCylinder(int slices, int stacks);
|
||||
void renderCone(float base, float height, int slices, int stacks);
|
||||
void renderGrid(int xDivisions, int yDivisions);
|
||||
|
||||
/// Loads geometry from the specified URL.
|
||||
|
@ -71,6 +72,7 @@ private:
|
|||
QHash<IntPair, VerticesIndices> _sphereVBOs;
|
||||
QHash<IntPair, VerticesIndices> _squareVBOs;
|
||||
QHash<IntPair, VerticesIndices> _halfCylinderVBOs;
|
||||
QHash<IntPair, VerticesIndices> _coneVBOs;
|
||||
QHash<IntPair, QOpenGLBuffer> _gridBuffers;
|
||||
|
||||
QHash<QUrl, QWeakPointer<NetworkGeometry> > _networkGeometry;
|
||||
|
|
|
@ -78,3 +78,11 @@ void AudioDeviceScriptingInterface::setReverb(bool reverb) {
|
|||
void AudioDeviceScriptingInterface::setReverbOptions(const AudioEffectOptions* options) {
|
||||
Application::getInstance()->getAudio()->setReverbOptions(options);
|
||||
}
|
||||
|
||||
void AudioDeviceScriptingInterface::toggleMute() {
|
||||
Application::getInstance()->getAudio()->toggleMute();
|
||||
}
|
||||
|
||||
bool AudioDeviceScriptingInterface::getMuted() {
|
||||
return Application::getInstance()->getAudio()->getMuted();
|
||||
}
|
||||
|
|
|
@ -41,6 +41,12 @@ public slots:
|
|||
void setInputVolume(float volume);
|
||||
void setReverb(bool reverb);
|
||||
void setReverbOptions(const AudioEffectOptions* options);
|
||||
|
||||
bool getMuted();
|
||||
void toggleMute();
|
||||
|
||||
signals:
|
||||
void muteToggled();
|
||||
};
|
||||
|
||||
#endif // hifi_AudioDeviceScriptingInterface_h
|
||||
|
|
|
@ -183,7 +183,7 @@ void ApplicationOverlay::computeOculusPickRay(float x, float y, glm::vec3& direc
|
|||
float dist = sqrt(x * x + y * y);
|
||||
float z = -sqrt(1.0f - dist * dist);
|
||||
|
||||
glm::vec3 relativePosition = myAvatar->getHead()->getEyePosition() +
|
||||
glm::vec3 relativePosition = myAvatar->getDefaultEyePosition() +
|
||||
glm::normalize(myAvatar->getOrientation() * glm::vec3(x, y, z));
|
||||
|
||||
//Rotate the UI pick ray by the avatar orientation
|
||||
|
@ -380,7 +380,7 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
|||
|
||||
glPushMatrix();
|
||||
const glm::quat& orientation = myAvatar->getOrientation();
|
||||
const glm::vec3& position = myAvatar->getHead()->getEyePosition();
|
||||
const glm::vec3& position = myAvatar->getDefaultEyePosition();
|
||||
|
||||
glm::mat4 rotation = glm::toMat4(orientation);
|
||||
|
||||
|
@ -414,7 +414,7 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
|||
|
||||
renderTexturedHemisphere();
|
||||
|
||||
renderPointersOculus(myAvatar->getHead()->getEyePosition());
|
||||
renderPointersOculus(myAvatar->getDefaultEyePosition());
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
@ -1220,7 +1220,7 @@ void ApplicationOverlay::renderTexturedHemisphere() {
|
|||
Application* application = Application::getInstance();
|
||||
MyAvatar* myAvatar = application->getAvatar();
|
||||
const glm::quat& orientation = myAvatar->getOrientation();
|
||||
const glm::vec3& position = myAvatar->getHead()->getEyePosition();
|
||||
const glm::vec3& position = myAvatar->getDefaultEyePosition();
|
||||
|
||||
glm::mat4 rotation = glm::toMat4(orientation);
|
||||
|
||||
|
|
|
@ -26,8 +26,9 @@ AudioInjector::AudioInjector(QObject* parent) :
|
|||
_sound(NULL),
|
||||
_options(),
|
||||
_shouldStop(false),
|
||||
_currentSendPosition(0),
|
||||
_loudness(0.0f)
|
||||
_loudness(0.0f),
|
||||
_isFinished(false),
|
||||
_currentSendPosition(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -35,8 +36,9 @@ AudioInjector::AudioInjector(Sound* sound, const AudioInjectorOptions& injectorO
|
|||
_sound(sound),
|
||||
_options(injectorOptions),
|
||||
_shouldStop(false),
|
||||
_currentSendPosition(0),
|
||||
_loudness(0.0f)
|
||||
_loudness(0.0f),
|
||||
_isFinished(false),
|
||||
_currentSendPosition(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -176,5 +178,6 @@ void AudioInjector::injectAudio() {
|
|||
}
|
||||
}
|
||||
|
||||
_isFinished = true;
|
||||
emit finished();
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
AudioInjector(QObject* parent);
|
||||
AudioInjector(Sound* sound, const AudioInjectorOptions& injectorOptions);
|
||||
|
||||
bool isFinished() const { return _isFinished; }
|
||||
int getCurrentSendPosition() const { return _currentSendPosition; }
|
||||
public slots:
|
||||
void injectAudio();
|
||||
|
@ -41,8 +42,10 @@ private:
|
|||
Sound* _sound;
|
||||
AudioInjectorOptions _options;
|
||||
bool _shouldStop;
|
||||
int _currentSendPosition;
|
||||
float _loudness;
|
||||
bool _isFinished;
|
||||
int _currentSendPosition;
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(AudioInjector*)
|
||||
|
|
|
@ -11,6 +11,26 @@
|
|||
|
||||
#include "AudioScriptingInterface.h"
|
||||
|
||||
AudioScriptingInterface& AudioScriptingInterface::getInstance() {
|
||||
static AudioScriptingInterface staticInstance;
|
||||
return staticInstance;
|
||||
}
|
||||
|
||||
void AudioScriptingInterface::stopAllInjectors() {
|
||||
QList<QPointer<AudioInjector> >::iterator injector = _activeInjectors.begin();
|
||||
while (injector != _activeInjectors.end()) {
|
||||
if (!injector->isNull()) {
|
||||
injector->data()->stop();
|
||||
|
||||
while (injector->data() && !injector->data()->isFinished()) {
|
||||
// wait for this injector to go down
|
||||
}
|
||||
}
|
||||
|
||||
injector = _activeInjectors.erase(injector);
|
||||
}
|
||||
}
|
||||
|
||||
AudioInjector* AudioScriptingInterface::playSound(Sound* sound, const AudioInjectorOptions* injectorOptions) {
|
||||
|
||||
if (sound->isStereo()) {
|
||||
|
@ -23,15 +43,18 @@ AudioInjector* AudioScriptingInterface::playSound(Sound* sound, const AudioInjec
|
|||
injector->moveToThread(injectorThread);
|
||||
|
||||
// start injecting when the injector thread starts
|
||||
connect(injectorThread, SIGNAL(started()), injector, SLOT(injectAudio()));
|
||||
connect(injectorThread, &QThread::started, injector, &AudioInjector::injectAudio);
|
||||
|
||||
// connect the right slots and signals so that the AudioInjector is killed once the injection is complete
|
||||
connect(injector, SIGNAL(finished()), injector, SLOT(deleteLater()));
|
||||
connect(injector, SIGNAL(finished()), injectorThread, SLOT(quit()));
|
||||
connect(injectorThread, SIGNAL(finished()), injectorThread, SLOT(deleteLater()));
|
||||
connect(injector, &AudioInjector::finished, injector, &AudioInjector::deleteLater);
|
||||
connect(injector, &AudioInjector::finished, injectorThread, &QThread::quit);
|
||||
connect(injector, &AudioInjector::finished, this, &AudioScriptingInterface::injectorStopped);
|
||||
connect(injectorThread, &QThread::finished, injectorThread, &QThread::deleteLater);
|
||||
|
||||
injectorThread->start();
|
||||
|
||||
_activeInjectors.append(QPointer<AudioInjector>(injector));
|
||||
|
||||
return injector;
|
||||
}
|
||||
|
||||
|
@ -53,24 +76,6 @@ float AudioScriptingInterface::getLoudness(AudioInjector* injector) {
|
|||
}
|
||||
}
|
||||
|
||||
void AudioScriptingInterface::startDrumSound(float volume, float frequency, float duration, float decay,
|
||||
const AudioInjectorOptions* injectorOptions) {
|
||||
|
||||
Sound* sound = new Sound(volume, frequency, duration, decay);
|
||||
AudioInjector* injector = new AudioInjector(sound, *injectorOptions);
|
||||
sound->setParent(injector);
|
||||
|
||||
QThread* injectorThread = new QThread();
|
||||
|
||||
injector->moveToThread(injectorThread);
|
||||
|
||||
// start injecting when the injector thread starts
|
||||
connect(injectorThread, SIGNAL(started()), injector, SLOT(injectAudio()));
|
||||
|
||||
// connect the right slots and signals so that the AudioInjector is killed once the injection is complete
|
||||
connect(injector, SIGNAL(finished()), injector, SLOT(deleteLater()));
|
||||
connect(injector, SIGNAL(finished()), injectorThread, SLOT(quit()));
|
||||
connect(injectorThread, SIGNAL(finished()), injectorThread, SLOT(deleteLater()));
|
||||
|
||||
injectorThread->start();
|
||||
void AudioScriptingInterface::injectorStopped() {
|
||||
_activeInjectors.removeAll(QPointer<AudioInjector>(reinterpret_cast<AudioInjector*>(sender())));
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#ifndef hifi_AudioScriptingInterface_h
|
||||
#define hifi_AudioScriptingInterface_h
|
||||
|
||||
#include <qpointer.h>
|
||||
|
||||
#include "AudioInjector.h"
|
||||
#include "Sound.h"
|
||||
|
||||
|
@ -19,13 +21,24 @@ const AudioInjectorOptions DEFAULT_INJECTOR_OPTIONS;
|
|||
|
||||
class AudioScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static AudioScriptingInterface& getInstance();
|
||||
|
||||
void stopAllInjectors();
|
||||
public slots:
|
||||
static AudioInjector* playSound(Sound* sound, const AudioInjectorOptions* injectorOptions = NULL);
|
||||
static void stopInjector(AudioInjector* injector);
|
||||
static bool isInjectorPlaying(AudioInjector* injector);
|
||||
|
||||
static float getLoudness(AudioInjector* injector);
|
||||
static void startDrumSound(float volume, float frequency, float duration, float decay,
|
||||
const AudioInjectorOptions* injectorOptions = NULL);
|
||||
|
||||
AudioInjector* playSound(Sound* sound, const AudioInjectorOptions* injectorOptions = NULL);
|
||||
void stopInjector(AudioInjector* injector);
|
||||
bool isInjectorPlaying(AudioInjector* injector);
|
||||
|
||||
void injectorStopped();
|
||||
|
||||
private:
|
||||
AudioScriptingInterface() {};
|
||||
QList< QPointer<AudioInjector> > _activeInjectors;
|
||||
|
||||
|
||||
};
|
||||
#endif // hifi_AudioScriptingInterface_h
|
||||
|
|
|
@ -290,7 +290,7 @@ void ScriptEngine::init() {
|
|||
qScriptRegisterMetaType(this, animationDetailsToScriptValue, animationDetailsFromScriptValue);
|
||||
|
||||
registerGlobalObject("Script", this);
|
||||
registerGlobalObject("Audio", &_audioScriptingInterface);
|
||||
registerGlobalObject("Audio", &AudioScriptingInterface::getInstance());
|
||||
registerGlobalObject("Controller", _controllerScriptingInterface);
|
||||
registerGlobalObject("Entities", &_entityScriptingInterface);
|
||||
registerGlobalObject("Quat", &_quatLibrary);
|
||||
|
|
|
@ -142,7 +142,6 @@ private:
|
|||
static EntityScriptingInterface _entityScriptingInterface;
|
||||
|
||||
AbstractControllerScriptingInterface* _controllerScriptingInterface;
|
||||
AudioScriptingInterface _audioScriptingInterface;
|
||||
AvatarData* _avatarData;
|
||||
QString _scriptName;
|
||||
QString _fileNameString;
|
||||
|
|
Loading…
Reference in a new issue