mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 18:23:54 +02:00
Merge pull request #2061 from PhilipRosedale/master
Added DC offset correction for crappy sound input devices, mousewheel voxel edit size
This commit is contained in:
commit
3a5bbfd989
11 changed files with 90 additions and 29 deletions
|
@ -23,6 +23,9 @@ var NEW_VOXEL_DISTANCE_FROM_CAMERA = 3.0;
|
|||
var ORBIT_RATE_ALTITUDE = 200.0;
|
||||
var ORBIT_RATE_AZIMUTH = 90.0;
|
||||
var PIXELS_PER_EXTRUDE_VOXEL = 16;
|
||||
var WHEEL_PIXELS_PER_SCALE_CHANGE = 100;
|
||||
var MAX_VOXEL_SCALE = 1.0;
|
||||
var MIN_VOXEL_SCALE = 1.0 / Math.pow(2.0, 8.0);
|
||||
|
||||
var zFightingSizeAdjust = 0.002; // used to adjust preview voxels to prevent z fighting
|
||||
var previewLineWidth = 1.5;
|
||||
|
@ -41,6 +44,7 @@ var orbitAzimuth = 0.0;
|
|||
var orbitAltitude = 0.0;
|
||||
var orbitCenter = { x: 0, y: 0, z: 0 };
|
||||
var orbitPosition = { x: 0, y: 0, z: 0 };
|
||||
var torsoToEyeVector = { x: 0, y: 0, z: 0 };
|
||||
var orbitRadius = 0.0;
|
||||
var extrudeDirection = { x: 0, y: 0, z: 0 };
|
||||
var extrudeScale = 0.0;
|
||||
|
@ -48,6 +52,8 @@ 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 };
|
||||
var wheelPixelsMoved = 0;
|
||||
|
||||
|
||||
var mouseX = 0;
|
||||
var mouseY = 0;
|
||||
|
@ -66,16 +72,15 @@ var numColors = 8;
|
|||
var whichColor = -1; // Starting color is 'Copy' mode
|
||||
|
||||
// Create sounds for adding, deleting, recoloring voxels
|
||||
var addSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+create.raw");
|
||||
var deleteSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+delete.raw");
|
||||
var changeColorSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+edit.raw");
|
||||
var addSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+create+2.raw");
|
||||
var deleteSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+delete+2.raw");
|
||||
var changeColorSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+edit+2.raw");
|
||||
var clickSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Switches+and+sliders/toggle+switch+-+medium.raw");
|
||||
var audioOptions = new AudioInjectionOptions();
|
||||
audioOptions.volume = 0.5;
|
||||
audioOptions.position = Vec3.sum(MyAvatar.position, { x: 0, y: 1, z: 0 } ); // start with audio slightly above the avatar
|
||||
|
||||
var editToolsOn = false; // starts out off
|
||||
|
||||
var editToolsOn = true; // starts out off
|
||||
|
||||
// previewAsVoxel - by default, we will preview adds/deletes/recolors as just 4 lines on the intersecting face. But if you
|
||||
// the preview to show a full voxel then set this to true and the voxel will be displayed for voxel editing
|
||||
|
@ -270,11 +275,16 @@ var pointerVoxelScale = 0; // this is the voxel scale used for click to add or d
|
|||
var pointerVoxelScaleSet = false; // if voxel scale has not yet been set, we use the intersection size
|
||||
|
||||
var pointerVoxelScaleSteps = 8; // the number of slider position steps
|
||||
var pointerVoxelScaleOriginStep = 3; // the position of slider for the 1 meter size voxel
|
||||
var pointerVoxelScaleOriginStep = 8; // the position of slider for the 1 meter size voxel
|
||||
var pointerVoxelScaleMin = Math.pow(2, (1-pointerVoxelScaleOriginStep));
|
||||
var pointerVoxelScaleMax = Math.pow(2, (pointerVoxelScaleSteps-pointerVoxelScaleOriginStep));
|
||||
var thumbDeltaPerStep = thumbExtents / (pointerVoxelScaleSteps - 1);
|
||||
|
||||
if (editToolsOn) {
|
||||
moveTools();
|
||||
}
|
||||
|
||||
|
||||
function calcThumbFromScale(scale) {
|
||||
var scaleLog = Math.log(scale)/Math.log(2);
|
||||
var thumbStep = scaleLog + pointerVoxelScaleOriginStep;
|
||||
|
@ -703,6 +713,9 @@ function startOrbitMode(event) {
|
|||
|
||||
// start orbit camera!
|
||||
var cameraPosition = Camera.getPosition();
|
||||
torsoToEyeVector = Vec3.subtract(cameraPosition, MyAvatar.position);
|
||||
torsoToEyeVector.x = 0.0;
|
||||
torsoToEyeVector.z = 0.0;
|
||||
oldMode = Camera.getMode();
|
||||
Camera.setMode("independent");
|
||||
Camera.keepLookingAt(intersection.intersection);
|
||||
|
@ -729,6 +742,7 @@ function handleOrbitingMove(event) {
|
|||
z:(Math.cos(orbitAltitude) * Math.sin(orbitAzimuth)) * orbitRadius };
|
||||
orbitPosition = Vec3.sum(orbitCenter, orbitVector);
|
||||
Camera.setPosition(orbitPosition);
|
||||
|
||||
mouseX = event.x;
|
||||
mouseY = event.y;
|
||||
//print("handleOrbitingMove...");
|
||||
|
@ -736,7 +750,7 @@ function handleOrbitingMove(event) {
|
|||
|
||||
function endOrbitMode(event) {
|
||||
var cameraOrientation = Camera.getOrientation();
|
||||
MyAvatar.position = Camera.getPosition();
|
||||
MyAvatar.position = Vec3.subtract(Camera.getPosition(), torsoToEyeVector);
|
||||
MyAvatar.headOrientation = cameraOrientation;
|
||||
Camera.stopLooking();
|
||||
Camera.setMode(oldMode);
|
||||
|
@ -795,8 +809,7 @@ function mousePressEvent(event) {
|
|||
if (!trackAsOrbitOrPan) {
|
||||
var clickedOnSomething = false;
|
||||
var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y});
|
||||
|
||||
print("clickedOverlay="+clickedOverlay);
|
||||
|
||||
|
||||
// If the user clicked on the thumb, handle the slider logic
|
||||
if (clickedOverlay == thumb) {
|
||||
|
@ -1318,6 +1331,32 @@ function update() {
|
|||
}
|
||||
}
|
||||
|
||||
function wheelEvent(event) {
|
||||
wheelPixelsMoved += event.delta;
|
||||
if (Math.abs(wheelPixelsMoved) > WHEEL_PIXELS_PER_SCALE_CHANGE)
|
||||
{
|
||||
if (!pointerVoxelScaleSet) {
|
||||
pointerVoxelScale = 1.0;
|
||||
pointerVoxelScaleSet = true;
|
||||
}
|
||||
if (wheelPixelsMoved > 0) {
|
||||
pointerVoxelScale /= 2.0;
|
||||
if (pointerVoxelScale < MIN_VOXEL_SCALE) {
|
||||
pointerVoxelScale = MIN_VOXEL_SCALE;
|
||||
}
|
||||
} else {
|
||||
pointerVoxelScale *= 2.0;
|
||||
if (pointerVoxelScale > MAX_VOXEL_SCALE) {
|
||||
pointerVoxelScale = MAX_VOXEL_SCALE;
|
||||
}
|
||||
}
|
||||
calcThumbFromScale(pointerVoxelScale);
|
||||
trackMouseEvent(event);
|
||||
wheelPixelsMoved = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Controller.wheelEvent.connect(wheelEvent);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||
|
|
|
@ -1492,6 +1492,8 @@ void Application::idle() {
|
|||
_idleLoopMeasuredJitter = _idleLoopStdev.getStDev();
|
||||
_idleLoopStdev.reset();
|
||||
}
|
||||
|
||||
_buckyBalls.simulate(timeSinceLastUpdate / 1000.f, Application::getInstance()->getAvatar()->getHandData());
|
||||
|
||||
// After finishing all of the above work, restart the idle timer, allowing 2ms to process events.
|
||||
idleTimer->start(2);
|
||||
|
@ -2814,6 +2816,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
"Application::displaySide() ... metavoxels...");
|
||||
_metavoxels.render();
|
||||
}
|
||||
|
||||
_buckyBalls.render();
|
||||
|
||||
// render particles...
|
||||
_particles.render();
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "Audio.h"
|
||||
|
||||
#include "BandwidthMeter.h"
|
||||
#include "BuckyBalls.h"
|
||||
#include "Camera.h"
|
||||
#include "DatagramProcessor.h"
|
||||
#include "Environment.h"
|
||||
|
@ -381,6 +382,8 @@ private:
|
|||
bool _justStarted;
|
||||
|
||||
Stars _stars;
|
||||
|
||||
BuckyBalls _buckyBalls;
|
||||
|
||||
VoxelSystem _voxels;
|
||||
VoxelTree _clipboard; // if I copy/paste
|
||||
|
|
|
@ -67,6 +67,7 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples, QObject* p
|
|||
_measuredJitter(0),
|
||||
_jitterBufferSamples(initialJitterBufferSamples),
|
||||
_lastInputLoudness(0),
|
||||
_dcOffset(0),
|
||||
_noiseGateMeasuredFloor(0),
|
||||
_noiseGateSampleCounter(0),
|
||||
_noiseGateOpen(false),
|
||||
|
@ -383,8 +384,13 @@ void Audio::handleAudioInput() {
|
|||
const int NOISE_GATE_WIDTH = 5;
|
||||
const int NOISE_GATE_CLOSE_FRAME_DELAY = 5;
|
||||
const int NOISE_GATE_FRAMES_TO_AVERAGE = 5;
|
||||
const float DC_OFFSET_AVERAGING = 0.99f;
|
||||
|
||||
float measuredDcOffset = 0.f;
|
||||
|
||||
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
|
||||
measuredDcOffset += monoAudioSamples[i];
|
||||
monoAudioSamples[i] -= (int16_t) _dcOffset;
|
||||
thisSample = fabsf(monoAudioSamples[i]);
|
||||
loudness += thisSample;
|
||||
// Noise Reduction: Count peaks above the average loudness
|
||||
|
@ -392,7 +398,17 @@ void Audio::handleAudioInput() {
|
|||
samplesOverNoiseGate++;
|
||||
}
|
||||
}
|
||||
_lastInputLoudness = loudness / NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||
|
||||
measuredDcOffset /= NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||
if (_dcOffset == 0.f) {
|
||||
// On first frame, copy over measured offset
|
||||
_dcOffset = measuredDcOffset;
|
||||
} else {
|
||||
_dcOffset = DC_OFFSET_AVERAGING * _dcOffset + (1.f - DC_OFFSET_AVERAGING) * measuredDcOffset;
|
||||
}
|
||||
|
||||
//
|
||||
_lastInputLoudness = fabs(loudness / NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||
|
||||
float averageOfAllSampleFrames = 0.f;
|
||||
_noiseSampleFrames[_noiseGateSampleCounter++] = _lastInputLoudness;
|
||||
|
@ -413,7 +429,7 @@ void Audio::handleAudioInput() {
|
|||
averageOfAllSampleFrames /= NUMBER_OF_NOISE_SAMPLE_FRAMES;
|
||||
_noiseGateMeasuredFloor = smallestSample;
|
||||
_noiseGateSampleCounter = 0;
|
||||
//qDebug("smallest sample = %.1f, avg of all = %.1f", _noiseGateMeasuredFloor, averageOfAllSampleFrames);
|
||||
|
||||
}
|
||||
|
||||
if (_noiseGateEnabled) {
|
||||
|
|
|
@ -110,6 +110,7 @@ private:
|
|||
float _measuredJitter;
|
||||
int16_t _jitterBufferSamples;
|
||||
float _lastInputLoudness;
|
||||
float _dcOffset;
|
||||
float _noiseGateMeasuredFloor;
|
||||
float* _noiseSampleFrames;
|
||||
int _noiseGateSampleCounter;
|
||||
|
|
|
@ -54,9 +54,12 @@ BuckyBalls::BuckyBalls() {
|
|||
}
|
||||
}
|
||||
|
||||
void BuckyBalls::grab(PalmData& palm, const glm::vec3& fingerTipPosition, glm::quat avatarOrientation, float deltaTime) {
|
||||
void BuckyBalls::grab(PalmData& palm, float deltaTime) {
|
||||
float penetration;
|
||||
glm::vec3 diff;
|
||||
FingerData& finger = palm.getFingers()[0]; // Sixense has only one finger
|
||||
glm::vec3 fingerTipPosition = finger.getTipPosition();
|
||||
|
||||
if (palm.getControllerButtons() & BUTTON_FWD) {
|
||||
if (!_bballIsGrabbed[palm.getSixenseID()]) {
|
||||
// Look for a ball to grab
|
||||
|
@ -89,7 +92,13 @@ const float COLLISION_BLEND_RATE = 0.5f;
|
|||
const float ATTRACTION_BLEND_RATE = 0.9f;
|
||||
const float ATTRACTION_VELOCITY_BLEND_RATE = 0.10f;
|
||||
|
||||
void BuckyBalls::simulate(float deltaTime) {
|
||||
void BuckyBalls::simulate(float deltaTime, const HandData* handData) {
|
||||
// First, update the grab behavior from the hand controllers
|
||||
for (size_t i = 0; i < handData->getNumPalms(); ++i) {
|
||||
PalmData palm = handData->getPalms()[i];
|
||||
grab(palm, deltaTime);
|
||||
}
|
||||
|
||||
// Look for collisions
|
||||
for (int i = 0; i < NUM_BBALLS; i++) {
|
||||
if (_bballElement[i] != 1) {
|
||||
|
|
|
@ -26,8 +26,8 @@ const int NUM_BBALLS = 200;
|
|||
class BuckyBalls {
|
||||
public:
|
||||
BuckyBalls();
|
||||
void grab(PalmData& palm, const glm::vec3& fingerTipPosition, glm::quat avatarOrientation, float deltaTime);
|
||||
void simulate(float deltaTime);
|
||||
void grab(PalmData& palm, float deltaTime);
|
||||
void simulate(float deltaTime, const HandData* handData);
|
||||
void render();
|
||||
|
||||
|
||||
|
|
|
@ -55,10 +55,6 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
|||
_collisionAge += deltaTime;
|
||||
}
|
||||
|
||||
if (isMine) {
|
||||
_buckyBalls.simulate(deltaTime);
|
||||
}
|
||||
|
||||
calculateGeometry();
|
||||
|
||||
if (isMine) {
|
||||
|
@ -69,8 +65,7 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
|||
FingerData& finger = palm.getFingers()[0]; // Sixense has only one finger
|
||||
glm::vec3 fingerTipPosition = finger.getTipPosition();
|
||||
|
||||
_buckyBalls.grab(palm, fingerTipPosition, _owningAvatar->getOrientation(), deltaTime);
|
||||
|
||||
|
||||
if (palm.getControllerButtons() & BUTTON_1) {
|
||||
if (glm::length(fingerTipPosition - _lastFingerAddVoxel) > (FINGERTIP_VOXEL_SIZE / 2.f)) {
|
||||
QColor paintColor = Menu::getInstance()->getActionForOption(MenuOption::VoxelPaintColor)->data().value<QColor>();
|
||||
|
@ -309,10 +304,6 @@ void Hand::render(bool isMine) {
|
|||
|
||||
_renderAlpha = 1.0;
|
||||
|
||||
if (isMine) {
|
||||
_buckyBalls.render();
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) {
|
||||
// draw a green sphere at hand joint location, which is actually near the wrist)
|
||||
for (size_t i = 0; i < getNumPalms(); i++) {
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <AudioScriptingInterface.h>
|
||||
#include <HandData.h>
|
||||
|
||||
#include "BuckyBalls.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "world.h"
|
||||
#include "VoxelSystem.h"
|
||||
|
@ -81,8 +80,6 @@ private:
|
|||
float _collisionAge;
|
||||
float _collisionDuration;
|
||||
|
||||
BuckyBalls _buckyBalls;
|
||||
|
||||
// private methods
|
||||
void setLeapHands(const std::vector<glm::vec3>& handPositions,
|
||||
const std::vector<glm::vec3>& handNormals);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "Application.h"
|
||||
#include "Avatar.h"
|
||||
#include "GeometryUtil.h"
|
||||
#include "Head.h"
|
||||
#include "Menu.h"
|
||||
#include "Util.h"
|
||||
|
|
|
@ -23,7 +23,7 @@ glm::vec3 Vec3::multiplyQbyV(const glm::quat& q, const glm::vec3& v) {
|
|||
return q * v;
|
||||
}
|
||||
|
||||
glm::vec3 Vec3::sum(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
glm::vec3 Vec3::sum(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
return v1 + v2;
|
||||
}
|
||||
glm::vec3 Vec3::subtract(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
|
|
Loading…
Reference in a new issue