mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 18:13:05 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into more_events
This commit is contained in:
commit
3bf8dd87e8
9 changed files with 256 additions and 88 deletions
170
examples/editVoxels.js
Normal file
170
examples/editVoxels.js
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
//
|
||||||
|
// editVoxels.js
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Philip Rosedale on February 8, 2014
|
||||||
|
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Captures mouse clicks and edits voxels accordingly.
|
||||||
|
//
|
||||||
|
// click = create a new voxel on this face, same color as old
|
||||||
|
// Alt + click = delete this voxel
|
||||||
|
// shift + click = recolor this voxel
|
||||||
|
//
|
||||||
|
// Click and drag to create more new voxels in the same direction
|
||||||
|
//
|
||||||
|
|
||||||
|
function vLength(v) {
|
||||||
|
return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
var key_alt = false;
|
||||||
|
var key_shift = false;
|
||||||
|
var isAdding = false;
|
||||||
|
|
||||||
|
var lastVoxelPosition = { x: 0, y: 0, z: 0 };
|
||||||
|
var lastVoxelColor = { red: 0, green: 0, blue: 0 };
|
||||||
|
var lastVoxelScale = 0;
|
||||||
|
var dragStart = { x: 0, y: 0 };
|
||||||
|
|
||||||
|
// Create a table of the different colors you can choose
|
||||||
|
var colors = new Array();
|
||||||
|
colors[0] = { red: 237, green: 175, blue: 0 };
|
||||||
|
colors[1] = { red: 61, green: 211, blue: 72 };
|
||||||
|
colors[2] = { red: 51, green: 204, blue: 204 };
|
||||||
|
colors[3] = { red: 63, green: 169, blue: 245 };
|
||||||
|
colors[4] = { red: 193, green: 99, blue: 122 };
|
||||||
|
colors[5] = { red: 255, green: 54, blue: 69 };
|
||||||
|
colors[6] = { red: 124, green: 36, blue: 36 };
|
||||||
|
colors[7] = { red: 63, green: 35, blue: 19 };
|
||||||
|
var numColors = 6;
|
||||||
|
var whichColor = 0;
|
||||||
|
|
||||||
|
// Create sounds for adding, deleting, recoloring voxels
|
||||||
|
var addSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Electronic/ElectronicBurst1.raw");
|
||||||
|
var deleteSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Bubbles/bubbles1.raw");
|
||||||
|
var changeColorSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Electronic/ElectronicBurst6.raw");
|
||||||
|
var audioOptions = new AudioInjectionOptions();
|
||||||
|
|
||||||
|
function mousePressEvent(event) {
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
|
var intersection = Voxels.findRayIntersection(pickRay);
|
||||||
|
audioOptions.volume = 1.0;
|
||||||
|
audioOptions.position = { x: intersection.voxel.x, y: intersection.voxel.y, z: intersection.voxel.z };
|
||||||
|
|
||||||
|
if (intersection.intersects) {
|
||||||
|
if (key_alt) {
|
||||||
|
// Delete voxel
|
||||||
|
Voxels.eraseVoxel(intersection.voxel.x, intersection.voxel.y, intersection.voxel.z, intersection.voxel.s);
|
||||||
|
Audio.playSound(deleteSound, audioOptions);
|
||||||
|
|
||||||
|
} else if (key_shift) {
|
||||||
|
// Recolor Voxel
|
||||||
|
whichColor++;
|
||||||
|
if (whichColor == numColors) whichColor = 0;
|
||||||
|
Voxels.setVoxel(intersection.voxel.x,
|
||||||
|
intersection.voxel.y,
|
||||||
|
intersection.voxel.z,
|
||||||
|
intersection.voxel.s,
|
||||||
|
colors[whichColor].red, colors[whichColor].green, colors[whichColor].blue);
|
||||||
|
Audio.playSound(changeColorSound, audioOptions);
|
||||||
|
} else {
|
||||||
|
// Add voxel on face
|
||||||
|
var newVoxel = {
|
||||||
|
x: intersection.voxel.x,
|
||||||
|
y: intersection.voxel.y,
|
||||||
|
z: intersection.voxel.z,
|
||||||
|
s: intersection.voxel.s,
|
||||||
|
red: intersection.voxel.red,
|
||||||
|
green: intersection.voxel.green,
|
||||||
|
blue: intersection.voxel.blue };
|
||||||
|
|
||||||
|
if (intersection.face == "MIN_X_FACE") {
|
||||||
|
newVoxel.x -= newVoxel.s;
|
||||||
|
} else if (intersection.face == "MAX_X_FACE") {
|
||||||
|
newVoxel.x += newVoxel.s;
|
||||||
|
} else if (intersection.face == "MIN_Y_FACE") {
|
||||||
|
newVoxel.y -= newVoxel.s;
|
||||||
|
} else if (intersection.face == "MAX_Y_FACE") {
|
||||||
|
newVoxel.y += newVoxel.s;
|
||||||
|
} else if (intersection.face == "MIN_Z_FACE") {
|
||||||
|
newVoxel.z -= newVoxel.s;
|
||||||
|
} else if (intersection.face == "MAX_Z_FACE") {
|
||||||
|
newVoxel.z += newVoxel.s;
|
||||||
|
}
|
||||||
|
|
||||||
|
Voxels.setVoxel(newVoxel.x, newVoxel.y, newVoxel.z, newVoxel.s, newVoxel.red, newVoxel.green, newVoxel.blue);
|
||||||
|
lastVoxelPosition = { x: newVoxel.x, y: newVoxel.y, z: newVoxel.z };
|
||||||
|
lastVoxelColor = { red: newVoxel.red, green: newVoxel.green, blue: newVoxel.blue };
|
||||||
|
lastVoxelScale = newVoxel.s;
|
||||||
|
|
||||||
|
Audio.playSound(addSound, audioOptions);
|
||||||
|
dragStart = { x: event.x, y: event.y };
|
||||||
|
isAdding = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyPressEvent(event) {
|
||||||
|
key_alt = event.isAlt;
|
||||||
|
key_shift = event.isShifted;
|
||||||
|
}
|
||||||
|
function keyReleaseEvent(event) {
|
||||||
|
key_alt = false;
|
||||||
|
key_shift = false;
|
||||||
|
}
|
||||||
|
function mouseMoveEvent(event) {
|
||||||
|
if (isAdding) {
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
|
var lastVoxelDistance = { x: pickRay.origin.x - lastVoxelPosition.x,
|
||||||
|
y: pickRay.origin.y - lastVoxelPosition.y,
|
||||||
|
z: pickRay.origin.z - lastVoxelPosition.z };
|
||||||
|
var distance = vLength(lastVoxelDistance);
|
||||||
|
var mouseSpot = { x: pickRay.direction.x * distance, y: pickRay.direction.y * distance, z: pickRay.direction.z * distance };
|
||||||
|
mouseSpot.x += pickRay.origin.x;
|
||||||
|
mouseSpot.y += pickRay.origin.y;
|
||||||
|
mouseSpot.z += pickRay.origin.z;
|
||||||
|
var dx = mouseSpot.x - lastVoxelPosition.x;
|
||||||
|
var dy = mouseSpot.y - lastVoxelPosition.y;
|
||||||
|
var dz = mouseSpot.z - lastVoxelPosition.z;
|
||||||
|
if (dx > lastVoxelScale) {
|
||||||
|
lastVoxelPosition.x += lastVoxelScale;
|
||||||
|
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
|
||||||
|
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
|
||||||
|
} else if (dx < -lastVoxelScale) {
|
||||||
|
lastVoxelPosition.x -= lastVoxelScale;
|
||||||
|
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
|
||||||
|
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
|
||||||
|
} else if (dy > lastVoxelScale) {
|
||||||
|
lastVoxelPosition.y += lastVoxelScale;
|
||||||
|
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
|
||||||
|
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
|
||||||
|
} else if (dy < -lastVoxelScale) {
|
||||||
|
lastVoxelPosition.y -= lastVoxelScale;
|
||||||
|
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
|
||||||
|
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
|
||||||
|
} else if (dz > lastVoxelScale) {
|
||||||
|
lastVoxelPosition.z += lastVoxelScale;
|
||||||
|
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
|
||||||
|
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
|
||||||
|
} else if (dz < -lastVoxelScale) {
|
||||||
|
lastVoxelPosition.z -= lastVoxelScale;
|
||||||
|
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
|
||||||
|
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseReleaseEvent(event) {
|
||||||
|
isAdding = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.mousePressEvent.connect(mousePressEvent);
|
||||||
|
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||||
|
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||||
|
Controller.keyPressEvent.connect(keyPressEvent);
|
||||||
|
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||||
|
|
||||||
|
function scriptEnding() {
|
||||||
|
}
|
||||||
|
Script.scriptEnding.connect(scriptEnding);
|
|
@ -4,6 +4,7 @@
|
||||||
//
|
//
|
||||||
// This sample script moves a voxel around like a bird and sometimes makes tweeting noises
|
// This sample script moves a voxel around like a bird and sometimes makes tweeting noises
|
||||||
//
|
//
|
||||||
|
|
||||||
function vLength(v) {
|
function vLength(v) {
|
||||||
return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
|
return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
|
||||||
}
|
}
|
||||||
|
@ -15,20 +16,24 @@ function randVector(a, b) {
|
||||||
var rval = { x: a + Math.random() * (b - a), y: a + Math.random() * (b - a), z: a + Math.random() * (b - a) };
|
var rval = { x: a + Math.random() * (b - a), y: a + Math.random() * (b - a), z: a + Math.random() * (b - a) };
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
function vMinus(a, b) {
|
function vMinus(a, b) {
|
||||||
var rval = { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };
|
var rval = { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
function vPlus(a, b) {
|
function vPlus(a, b) {
|
||||||
var rval = { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
|
var rval = { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
function vCopy(a, b) {
|
function vCopy(a, b) {
|
||||||
a.x = b.x;
|
a.x = b.x;
|
||||||
a.y = b.y;
|
a.y = b.y;
|
||||||
a.z = b.z;
|
a.z = b.z;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a vector which is fraction of the way between a and b
|
// Returns a vector which is fraction of the way between a and b
|
||||||
function vInterpolate(a, b, fraction) {
|
function vInterpolate(a, b, fraction) {
|
||||||
var rval = { x: a.x + (b.x - a.x) * fraction, y: a.y + (b.y - a.y) * fraction, z: a.z + (b.z - a.z) * fraction };
|
var rval = { x: a.x + (b.x - a.x) * fraction, y: a.y + (b.y - a.y) * fraction, z: a.z + (b.z - a.z) * fraction };
|
||||||
|
@ -62,6 +67,7 @@ if (which < 0.2) {
|
||||||
size = 0.15;
|
size = 0.15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var startTimeInSeconds = new Date().getTime() / 1000;
|
var startTimeInSeconds = new Date().getTime() / 1000;
|
||||||
|
|
||||||
var birdLifetime = 20; // lifetime of the bird in seconds!
|
var birdLifetime = 20; // lifetime of the bird in seconds!
|
||||||
|
@ -72,15 +78,19 @@ var frame = 0;
|
||||||
var moving = false;
|
var moving = false;
|
||||||
var tweeting = 0;
|
var tweeting = 0;
|
||||||
var moved = false;
|
var moved = false;
|
||||||
var CHANCE_OF_MOVING = 0.05;
|
|
||||||
|
var CHANCE_OF_MOVING = 0.00;
|
||||||
|
var CHANCE_OF_FLAPPING = 0.05;
|
||||||
var CHANCE_OF_TWEETING = 0.05;
|
var CHANCE_OF_TWEETING = 0.05;
|
||||||
var START_HEIGHT_ABOVE_ME = 1.5;
|
var START_HEIGHT_ABOVE_ME = 1.5;
|
||||||
|
var BIRD_GRAVITY = -0.1;
|
||||||
|
var BIRD_FLAP = 1.0;
|
||||||
var myPosition = MyAvatar.position;
|
var myPosition = MyAvatar.position;
|
||||||
var properties = {
|
var properties = {
|
||||||
lifetime: birdLifetime,
|
lifetime: birdLifetime,
|
||||||
position: { x: myPosition.x, y: myPosition.y + START_HEIGHT_ABOVE_ME, z: myPosition.z },
|
position: { x: myPosition.x, y: myPosition.y + START_HEIGHT_ABOVE_ME, z: myPosition.z },
|
||||||
velocity: { x: 0, y: 0, z: 0 },
|
velocity: { x: 0, y: Math.random() * BIRD_FLAP, z: 0 },
|
||||||
gravity: { x: 0, y: 0, z: 0 },
|
gravity: { x: 0, y: BIRD_GRAVITY, z: 0 },
|
||||||
radius : 0.1,
|
radius : 0.1,
|
||||||
color: { red: 0,
|
color: { red: 0,
|
||||||
green: 255,
|
green: 255,
|
||||||
|
@ -94,6 +104,7 @@ function moveBird() {
|
||||||
// check to see if we've been running long enough that our bird is dead
|
// check to see if we've been running long enough that our bird is dead
|
||||||
var nowTimeInSeconds = new Date().getTime() / 1000;
|
var nowTimeInSeconds = new Date().getTime() / 1000;
|
||||||
if ((nowTimeInSeconds - startTimeInSeconds) >= birdLifetime) {
|
if ((nowTimeInSeconds - startTimeInSeconds) >= birdLifetime) {
|
||||||
|
|
||||||
print("our bird is dying, stop our script");
|
print("our bird is dying, stop our script");
|
||||||
Script.stop();
|
Script.stop();
|
||||||
return;
|
return;
|
||||||
|
@ -115,11 +126,22 @@ function moveBird() {
|
||||||
} else {
|
} else {
|
||||||
tweeting -= 1;
|
tweeting -= 1;
|
||||||
}
|
}
|
||||||
|
if (Math.random() < CHANCE_OF_FLAPPING) {
|
||||||
|
// Add a little upward impulse to our bird
|
||||||
|
// TODO: Get velocity
|
||||||
|
//
|
||||||
|
var newProperties = {
|
||||||
|
velocity: { x:0.0, y: Math.random() * BIRD_FLAP, z: 0.0 }
|
||||||
|
};
|
||||||
|
Particles.editParticle(particleID, newProperties);
|
||||||
|
print("flap!");
|
||||||
|
}
|
||||||
// Moving behavior
|
// Moving behavior
|
||||||
if (moving == false) {
|
if (moving == false) {
|
||||||
if (Math.random() < CHANCE_OF_MOVING) {
|
if (Math.random() < CHANCE_OF_MOVING) {
|
||||||
targetPosition = randVector(- range, range);
|
targetPosition = randVector(-range, range);
|
||||||
targetPosition = vPlus(targetPosition, myPosition);
|
targetPosition = vPlus(targetPosition, myPosition);
|
||||||
|
|
||||||
if (targetPosition.x < 0) {
|
if (targetPosition.x < 0) {
|
||||||
targetPosition.x = 0;
|
targetPosition.x = 0;
|
||||||
}
|
}
|
||||||
|
@ -170,5 +192,6 @@ function moveBird() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// register the call back so it fires before each data send
|
// register the call back so it fires before each data send
|
||||||
Script.willSendVisualDataCallback.connect(moveBird);
|
Script.willSendVisualDataCallback.connect(moveBird);
|
||||||
|
|
|
@ -135,7 +135,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
_isTouchPressed(false),
|
_isTouchPressed(false),
|
||||||
_mousePressed(false),
|
_mousePressed(false),
|
||||||
_isHoverVoxel(false),
|
_isHoverVoxel(false),
|
||||||
_isHoverVoxelSounding(false),
|
|
||||||
_mouseVoxelScale(1.0f / 1024.0f),
|
_mouseVoxelScale(1.0f / 1024.0f),
|
||||||
_mouseVoxelScaleInitialized(false),
|
_mouseVoxelScaleInitialized(false),
|
||||||
_justEditedVoxel(false),
|
_justEditedVoxel(false),
|
||||||
|
@ -1199,7 +1198,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_isHoverVoxel) {
|
if (_isHoverVoxel) {
|
||||||
_myAvatar->orbit(getMouseVoxelWorldCoordinates(_hoverVoxel), deltaX, deltaY);
|
//_myAvatar->orbit(getMouseVoxelWorldCoordinates(_hoverVoxel), deltaX, deltaY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1219,11 +1218,6 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool MAKE_SOUND_ON_VOXEL_HOVER = false;
|
|
||||||
const bool MAKE_SOUND_ON_VOXEL_CLICK = true;
|
|
||||||
const float HOVER_VOXEL_FREQUENCY = 7040.f;
|
|
||||||
const float HOVER_VOXEL_DECAY = 0.999f;
|
|
||||||
|
|
||||||
void Application::mousePressEvent(QMouseEvent* event) {
|
void Application::mousePressEvent(QMouseEvent* event) {
|
||||||
_controllerScriptingInterface.emitMousePressEvent(event); // send events to any registered scripts
|
_controllerScriptingInterface.emitMousePressEvent(event); // send events to any registered scripts
|
||||||
|
|
||||||
|
@ -1263,37 +1257,6 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
||||||
pasteVoxels();
|
pasteVoxels();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::VoxelDeleteMode) &&
|
|
||||||
MAKE_SOUND_ON_VOXEL_CLICK && _isHoverVoxel && !_isHoverVoxelSounding) {
|
|
||||||
_hoverVoxelOriginalColor[0] = _hoverVoxel.red;
|
|
||||||
_hoverVoxelOriginalColor[1] = _hoverVoxel.green;
|
|
||||||
_hoverVoxelOriginalColor[2] = _hoverVoxel.blue;
|
|
||||||
_hoverVoxelOriginalColor[3] = 1;
|
|
||||||
const float RED_CLICK_FREQUENCY = 1000.f;
|
|
||||||
const float GREEN_CLICK_FREQUENCY = 1250.f;
|
|
||||||
const float BLUE_CLICK_FREQUENCY = 1330.f;
|
|
||||||
const float MIDDLE_A_FREQUENCY = 440.f;
|
|
||||||
float frequency = MIDDLE_A_FREQUENCY +
|
|
||||||
(_hoverVoxel.red / 255.f * RED_CLICK_FREQUENCY +
|
|
||||||
_hoverVoxel.green / 255.f * GREEN_CLICK_FREQUENCY +
|
|
||||||
_hoverVoxel.blue / 255.f * BLUE_CLICK_FREQUENCY) / 3.f;
|
|
||||||
|
|
||||||
_audio.startCollisionSound(1.0, frequency, 0.0, HOVER_VOXEL_DECAY, false);
|
|
||||||
_isHoverVoxelSounding = true;
|
|
||||||
|
|
||||||
const float PERCENTAGE_TO_MOVE_TOWARD = 0.90f;
|
|
||||||
glm::vec3 newTarget = getMouseVoxelWorldCoordinates(_hoverVoxel);
|
|
||||||
glm::vec3 myPosition = _myAvatar->getPosition();
|
|
||||||
|
|
||||||
// If there is not an action tool set (add, delete, color), move to this voxel
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::ClickToFly) &&
|
|
||||||
!(Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode) ||
|
|
||||||
Menu::getInstance()->isOptionChecked(MenuOption::VoxelDeleteMode) ||
|
|
||||||
Menu::getInstance()->isOptionChecked(MenuOption::VoxelColorMode))) {
|
|
||||||
_myAvatar->setMoveTarget(myPosition + (newTarget - myPosition) * PERCENTAGE_TO_MOVE_TOWARD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (event->button() == Qt::RightButton && Menu::getInstance()->isVoxelModeActionChecked()) {
|
} else if (event->button() == Qt::RightButton && Menu::getInstance()->isVoxelModeActionChecked()) {
|
||||||
deleteVoxelUnderCursor();
|
deleteVoxelUnderCursor();
|
||||||
}
|
}
|
||||||
|
@ -2044,44 +2007,11 @@ void Application::updateHoverVoxels(float deltaTime, float& distance, BoxFace& f
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels()");
|
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels()");
|
||||||
|
|
||||||
// If we have clicked on a voxel, update it's color
|
// Check for a new hover voxel
|
||||||
if (_isHoverVoxelSounding) {
|
if (!_mousePressed) {
|
||||||
VoxelTreeElement* hoveredNode = _voxels.getVoxelAt(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s);
|
{
|
||||||
if (hoveredNode) {
|
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()");
|
||||||
float bright = _audio.getCollisionSoundMagnitude();
|
_isHoverVoxel = _voxels.findRayIntersection(_mouseRayOrigin, _mouseRayDirection, _hoverVoxel, distance, face);
|
||||||
nodeColor clickColor = { 255 * bright + _hoverVoxelOriginalColor[0] * (1.f - bright),
|
|
||||||
_hoverVoxelOriginalColor[1] * (1.f - bright),
|
|
||||||
_hoverVoxelOriginalColor[2] * (1.f - bright), 1 };
|
|
||||||
hoveredNode->setColor(clickColor);
|
|
||||||
if (bright < 0.01f) {
|
|
||||||
hoveredNode->setColor(_hoverVoxelOriginalColor);
|
|
||||||
_isHoverVoxelSounding = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Voxel is not found, clear all
|
|
||||||
_isHoverVoxelSounding = false;
|
|
||||||
_isHoverVoxel = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Check for a new hover voxel
|
|
||||||
glm::vec4 oldVoxel(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s);
|
|
||||||
// only do this work if MAKE_SOUND_ON_VOXEL_HOVER or MAKE_SOUND_ON_VOXEL_CLICK is enabled,
|
|
||||||
// and make sure the tree is not already busy... because otherwise you'll have to wait.
|
|
||||||
if (!_mousePressed) {
|
|
||||||
{
|
|
||||||
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()");
|
|
||||||
_isHoverVoxel = _voxels.findRayIntersection(_mouseRayOrigin, _mouseRayDirection, _hoverVoxel, distance, face);
|
|
||||||
}
|
|
||||||
if (MAKE_SOUND_ON_VOXEL_HOVER && _isHoverVoxel &&
|
|
||||||
glm::vec4(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s) != oldVoxel) {
|
|
||||||
|
|
||||||
_hoverVoxelOriginalColor[0] = _hoverVoxel.red;
|
|
||||||
_hoverVoxelOriginalColor[1] = _hoverVoxel.green;
|
|
||||||
_hoverVoxelOriginalColor[2] = _hoverVoxel.blue;
|
|
||||||
_hoverVoxelOriginalColor[3] = 1;
|
|
||||||
_audio.startCollisionSound(1.0, HOVER_VOXEL_FREQUENCY * _hoverVoxel.s * TREE_SCALE, 0.0, HOVER_VOXEL_DECAY, false);
|
|
||||||
_isHoverVoxelSounding = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,8 +419,6 @@ private:
|
||||||
|
|
||||||
VoxelDetail _hoverVoxel; // Stuff about the voxel I am hovering or clicking
|
VoxelDetail _hoverVoxel; // Stuff about the voxel I am hovering or clicking
|
||||||
bool _isHoverVoxel;
|
bool _isHoverVoxel;
|
||||||
bool _isHoverVoxelSounding;
|
|
||||||
nodeColor _hoverVoxelOriginalColor;
|
|
||||||
|
|
||||||
VoxelDetail _mouseVoxel; // details of the voxel to be edited
|
VoxelDetail _mouseVoxel; // details of the voxel to be edited
|
||||||
float _mouseVoxelScale; // the scale for adding/removing voxels
|
float _mouseVoxelScale; // the scale for adding/removing voxels
|
||||||
|
|
|
@ -65,6 +65,10 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples, QObject* p
|
||||||
_measuredJitter(0),
|
_measuredJitter(0),
|
||||||
_jitterBufferSamples(initialJitterBufferSamples),
|
_jitterBufferSamples(initialJitterBufferSamples),
|
||||||
_lastInputLoudness(0),
|
_lastInputLoudness(0),
|
||||||
|
_averageInputLoudness(0),
|
||||||
|
_noiseGateOpen(false),
|
||||||
|
_noiseGateEnabled(true),
|
||||||
|
_noiseGateFramesToClose(0),
|
||||||
_lastVelocity(0),
|
_lastVelocity(0),
|
||||||
_lastAcceleration(0),
|
_lastAcceleration(0),
|
||||||
_totalPacketsReceived(0),
|
_totalPacketsReceived(0),
|
||||||
|
@ -348,12 +352,40 @@ void Audio::handleAudioInput() {
|
||||||
_inputFormat, _desiredInputFormat);
|
_inputFormat, _desiredInputFormat);
|
||||||
|
|
||||||
float loudness = 0;
|
float loudness = 0;
|
||||||
|
float thisSample = 0;
|
||||||
|
int samplesOverNoiseGate = 0;
|
||||||
|
|
||||||
|
const float NOISE_GATE_HEIGHT = 3.f;
|
||||||
|
const int NOISE_GATE_WIDTH = 5;
|
||||||
|
const int NOISE_GATE_CLOSE_FRAME_DELAY = 30;
|
||||||
|
|
||||||
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
|
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
|
||||||
loudness += fabsf(monoAudioSamples[i]);
|
thisSample = fabsf(monoAudioSamples[i]);
|
||||||
|
loudness += thisSample;
|
||||||
|
// Noise Reduction: Count peaks above the average loudness
|
||||||
|
if (thisSample > (_averageInputLoudness * NOISE_GATE_HEIGHT)) {
|
||||||
|
samplesOverNoiseGate++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastInputLoudness = loudness / NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
_lastInputLoudness = loudness / NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||||
|
const float LOUDNESS_AVERAGING_FRAMES = 1000.f; // This will be about 10 seconds
|
||||||
|
_averageInputLoudness = (1.f - 1.f / LOUDNESS_AVERAGING_FRAMES) * _averageInputLoudness + (1.f / LOUDNESS_AVERAGING_FRAMES) * _lastInputLoudness;
|
||||||
|
|
||||||
|
if (_noiseGateEnabled) {
|
||||||
|
if (samplesOverNoiseGate > NOISE_GATE_WIDTH) {
|
||||||
|
_noiseGateOpen = true;
|
||||||
|
_noiseGateFramesToClose = NOISE_GATE_CLOSE_FRAME_DELAY;
|
||||||
|
} else {
|
||||||
|
if (--_noiseGateFramesToClose == 0) {
|
||||||
|
_noiseGateOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!_noiseGateOpen) {
|
||||||
|
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
|
||||||
|
monoAudioSamples[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add input data just written to the scope
|
// add input data just written to the scope
|
||||||
QMetaObject::invokeMethod(_scope, "addSamples", Qt::QueuedConnection,
|
QMetaObject::invokeMethod(_scope, "addSamples", Qt::QueuedConnection,
|
||||||
|
@ -524,6 +556,10 @@ void Audio::toggleMute() {
|
||||||
muteToggled();
|
muteToggled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Audio::toggleAudioNoiseReduction() {
|
||||||
|
_noiseGateEnabled = !_noiseGateEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
void Audio::render(int screenWidth, int screenHeight) {
|
void Audio::render(int screenWidth, int screenHeight) {
|
||||||
if (_audioInput && _audioOutput) {
|
if (_audioInput && _audioOutput) {
|
||||||
glLineWidth(2.0);
|
glLineWidth(2.0);
|
||||||
|
|
|
@ -45,7 +45,9 @@ public:
|
||||||
|
|
||||||
void render(int screenWidth, int screenHeight);
|
void render(int screenWidth, int screenHeight);
|
||||||
|
|
||||||
float getLastInputLoudness() const { return _lastInputLoudness; }
|
float getLastInputLoudness() const { return glm::max(_lastInputLoudness - _averageInputLoudness, 0.f); }
|
||||||
|
|
||||||
|
void setNoiseGateEnabled(bool noiseGateEnabled) { _noiseGateEnabled = noiseGateEnabled; }
|
||||||
|
|
||||||
void setLastAcceleration(const glm::vec3 lastAcceleration) { _lastAcceleration = lastAcceleration; }
|
void setLastAcceleration(const glm::vec3 lastAcceleration) { _lastAcceleration = lastAcceleration; }
|
||||||
void setLastVelocity(const glm::vec3 lastVelocity) { _lastVelocity = lastVelocity; }
|
void setLastVelocity(const glm::vec3 lastVelocity) { _lastVelocity = lastVelocity; }
|
||||||
|
@ -73,6 +75,7 @@ public slots:
|
||||||
void handleAudioInput();
|
void handleAudioInput();
|
||||||
void reset();
|
void reset();
|
||||||
void toggleMute();
|
void toggleMute();
|
||||||
|
void toggleAudioNoiseReduction();
|
||||||
|
|
||||||
virtual void handleAudioByteArray(const QByteArray& audioByteArray);
|
virtual void handleAudioByteArray(const QByteArray& audioByteArray);
|
||||||
|
|
||||||
|
@ -106,6 +109,10 @@ private:
|
||||||
float _measuredJitter;
|
float _measuredJitter;
|
||||||
int16_t _jitterBufferSamples;
|
int16_t _jitterBufferSamples;
|
||||||
float _lastInputLoudness;
|
float _lastInputLoudness;
|
||||||
|
float _averageInputLoudness;
|
||||||
|
bool _noiseGateOpen;
|
||||||
|
bool _noiseGateEnabled;
|
||||||
|
int _noiseGateFramesToClose;
|
||||||
glm::vec3 _lastVelocity;
|
glm::vec3 _lastVelocity;
|
||||||
glm::vec3 _lastAcceleration;
|
glm::vec3 _lastAcceleration;
|
||||||
int _totalPacketsReceived;
|
int _totalPacketsReceived;
|
||||||
|
|
|
@ -457,6 +457,11 @@ Menu::Menu() :
|
||||||
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P);
|
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P);
|
||||||
|
|
||||||
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
|
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
|
||||||
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioNoiseReduction,
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
appInstance->getAudio(),
|
||||||
|
SLOT(toggleAudioNoiseReduction()));
|
||||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio);
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio);
|
||||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio);
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio);
|
||||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteAudio,
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteAudio,
|
||||||
|
|
|
@ -187,6 +187,7 @@ namespace MenuOption {
|
||||||
const QString Enable3DTVMode = "Enable 3DTV Mode";
|
const QString Enable3DTVMode = "Enable 3DTV Mode";
|
||||||
const QString EnableOcclusionCulling = "Enable Occlusion Culling";
|
const QString EnableOcclusionCulling = "Enable Occlusion Culling";
|
||||||
const QString EnableVoxelPacketCompression = "Enable Voxel Packet Compression";
|
const QString EnableVoxelPacketCompression = "Enable Voxel Packet Compression";
|
||||||
|
const QString AudioNoiseReduction = "Audio Noise Reduction";
|
||||||
const QString EchoServerAudio = "Echo Server Audio";
|
const QString EchoServerAudio = "Echo Server Audio";
|
||||||
const QString EchoLocalAudio = "Echo Local Audio";
|
const QString EchoLocalAudio = "Echo Local Audio";
|
||||||
const QString MuteAudio = "Mute Microphone";
|
const QString MuteAudio = "Mute Microphone";
|
||||||
|
|
|
@ -107,7 +107,6 @@ QByteArray AvatarData::toByteArray() {
|
||||||
destinationBuffer += sizeof(_headData->_lookAtPosition);
|
destinationBuffer += sizeof(_headData->_lookAtPosition);
|
||||||
|
|
||||||
// Instantaneous audio loudness (used to drive facial animation)
|
// Instantaneous audio loudness (used to drive facial animation)
|
||||||
//destinationBuffer += packFloatToByte(destinationBuffer, std::min(MAX_AUDIO_LOUDNESS, _audioLoudness), MAX_AUDIO_LOUDNESS);
|
|
||||||
memcpy(destinationBuffer, &_headData->_audioLoudness, sizeof(float));
|
memcpy(destinationBuffer, &_headData->_audioLoudness, sizeof(float));
|
||||||
destinationBuffer += sizeof(float);
|
destinationBuffer += sizeof(float);
|
||||||
|
|
||||||
|
@ -215,7 +214,6 @@ int AvatarData::parseData(const QByteArray& packet) {
|
||||||
sourceBuffer += sizeof(_headData->_lookAtPosition);
|
sourceBuffer += sizeof(_headData->_lookAtPosition);
|
||||||
|
|
||||||
// Instantaneous audio loudness (used to drive facial animation)
|
// Instantaneous audio loudness (used to drive facial animation)
|
||||||
//sourceBuffer += unpackFloatFromByte(sourceBuffer, _audioLoudness, MAX_AUDIO_LOUDNESS);
|
|
||||||
memcpy(&_headData->_audioLoudness, sourceBuffer, sizeof(float));
|
memcpy(&_headData->_audioLoudness, sourceBuffer, sizeof(float));
|
||||||
sourceBuffer += sizeof(float);
|
sourceBuffer += sizeof(float);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue