From 8a16986294bb601e1e9a5d1689c4404589e4c9af Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 15 Apr 2014 09:58:35 -0700 Subject: [PATCH] add sliders for reflection, diffusion, absorption --- examples/audioReflectorTools.js | 297 ++++++++++++++++++++++++++++--- interface/src/AudioReflector.cpp | 26 ++- interface/src/AudioReflector.h | 10 +- interface/src/ui/Stats.cpp | 14 +- 4 files changed, 309 insertions(+), 38 deletions(-) diff --git a/examples/audioReflectorTools.js b/examples/audioReflectorTools.js index ae9f43fddb..0467a4f937 100644 --- a/examples/audioReflectorTools.js +++ b/examples/audioReflectorTools.js @@ -14,12 +14,62 @@ var delayScale = 100.0; var fanoutScale = 10.0; var speedScale = 20; var factorScale = 5.0; +var reflectiveScale = 100.0; +var diffusionScale = 100.0; +var absorptionScale = 100.0; + +// these three properties are bound together, if you change one, the others will also change +var reflectiveRatio = AudioReflector.getReflectiveRatio(); +var diffusionRatio = AudioReflector.getDiffusionRatio(); +var absorptionRatio = AudioReflector.getAbsorptionRatio(); + +var reflectiveThumbX; +var diffusionThumbX; +var absorptionThumbX; + +function setReflectiveRatio(reflective) { + var total = diffusionRatio + absorptionRatio + (reflective / reflectiveScale); + diffusionRatio = diffusionRatio / total; + absorptionRatio = absorptionRatio / total; + reflectiveRatio = (reflective / reflectiveScale) / total; + updateRatioValues(); +} + +function setDiffusionRatio(diffusion) { + var total = (diffusion / diffusionScale) + absorptionRatio + reflectiveRatio; + diffusionRatio = (diffusion / diffusionScale) / total; + absorptionRatio = absorptionRatio / total; + reflectiveRatio = reflectiveRatio / total; + updateRatioValues(); +} + +function setAbsorptionRatio(absorption) { + var total = diffusionRatio + (absorption / absorptionScale) + reflectiveRatio; + diffusionRatio = diffusionRatio / total; + absorptionRatio = (absorption / absorptionScale) / total; + reflectiveRatio = reflectiveRatio / total; + updateRatioValues(); +} + +function updateRatioSliders() { + reflectiveThumbX = reflectiveMinThumbX + ((reflectiveMaxThumbX - reflectiveMinThumbX) * reflectiveRatio); + diffusionThumbX = diffusionMinThumbX + ((diffusionMaxThumbX - diffusionMinThumbX) * diffusionRatio); + absorptionThumbX = absorptionMinThumbX + ((absorptionMaxThumbX - absorptionMinThumbX) * absorptionRatio); + + Overlays.editOverlay(reflectiveThumb, { x: reflectiveThumbX } ); + Overlays.editOverlay(diffusionThumb, { x: diffusionThumbX } ); + Overlays.editOverlay(absorptionThumb, { x: absorptionThumbX } ); +} + +function updateRatioValues() { + AudioReflector.setReflectiveRatio(reflectiveRatio); + AudioReflector.setDiffusionRatio(diffusionRatio); + AudioReflector.setAbsorptionRatio(absorptionRatio); +} var topY = 250; var sliderHeight = 35; -// This will create a couple of image overlays that make a "slider", we will demonstrate how to trap mouse messages to -// move the slider var delayY = topY; topY += sliderHeight; var delayLabel = Overlays.addOverlay("text", { @@ -28,7 +78,7 @@ var delayLabel = Overlays.addOverlay("text", { width: 60, height: sliderHeight, color: { red: 0, green: 0, blue: 0}, - textColor: { red: 255, green: 0, blue: 0}, + textColor: { red: 255, green: 255, blue: 255}, topMargin: 12, leftMargin: 5, text: "Delay:" @@ -43,7 +93,7 @@ var delaySlider = Overlays.addOverlay("image", { alpha: 1 }); -// This is the thumb of our slider + var delayMinThumbX = 110; var delayMaxThumbX = delayMinThumbX + 110; var delayThumbX = delayMinThumbX + ((delayMaxThumbX - delayMinThumbX) * (AudioReflector.getPreDelay() / delayScale)); @@ -57,8 +107,6 @@ var delayThumb = Overlays.addOverlay("image", { alpha: 1 }); -// This will create a couple of image overlays that make a "slider", we will demonstrate how to trap mouse messages to -// move the slider var fanoutY = topY; topY += sliderHeight; @@ -68,7 +116,7 @@ var fanoutLabel = Overlays.addOverlay("text", { width: 60, height: sliderHeight, color: { red: 0, green: 0, blue: 0}, - textColor: { red: 255, green: 0, blue: 0}, + textColor: { red: 255, green: 255, blue: 255}, topMargin: 12, leftMargin: 5, text: "Fanout:" @@ -83,7 +131,7 @@ var fanoutSlider = Overlays.addOverlay("image", { alpha: 1 }); -// This is the thumb of our slider + var fanoutMinThumbX = 110; var fanoutMaxThumbX = fanoutMinThumbX + 110; var fanoutThumbX = fanoutMinThumbX + ((fanoutMaxThumbX - fanoutMinThumbX) * (AudioReflector.getDiffusionFanout() / fanoutScale)); @@ -98,8 +146,6 @@ var fanoutThumb = Overlays.addOverlay("image", { }); -// This will create a couple of image overlays that make a "slider", we will demonstrate how to trap mouse messages to -// move the slider var speedY = topY; topY += sliderHeight; @@ -109,7 +155,7 @@ var speedLabel = Overlays.addOverlay("text", { width: 60, height: sliderHeight, color: { red: 0, green: 0, blue: 0}, - textColor: { red: 255, green: 0, blue: 0}, + textColor: { red: 255, green: 255, blue: 255}, topMargin: 6, leftMargin: 5, text: "Speed\nin ms/m:" @@ -124,7 +170,7 @@ var speedSlider = Overlays.addOverlay("image", { alpha: 1 }); -// This is the thumb of our slider + var speedMinThumbX = 110; var speedMaxThumbX = speedMinThumbX + 110; var speedThumbX = speedMinThumbX + ((speedMaxThumbX - speedMinThumbX) * (AudioReflector.getSoundMsPerMeter() / speedScale)); @@ -138,8 +184,6 @@ var speedThumb = Overlays.addOverlay("image", { alpha: 1 }); -// This will create a couple of image overlays that make a "slider", we will demonstrate how to trap mouse messages to -// move the slider var factorY = topY; topY += sliderHeight; @@ -149,7 +193,7 @@ var factorLabel = Overlays.addOverlay("text", { width: 60, height: sliderHeight, color: { red: 0, green: 0, blue: 0}, - textColor: { red: 255, green: 0, blue: 0}, + textColor: { red: 255, green: 255, blue: 255}, topMargin: 6, leftMargin: 5, text: "Attenuation\nFactor:" @@ -165,7 +209,7 @@ var factorSlider = Overlays.addOverlay("image", { alpha: 1 }); -// This is the thumb of our slider + var factorMinThumbX = 110; var factorMaxThumbX = factorMinThumbX + 110; var factorThumbX = factorMinThumbX + ((factorMaxThumbX - factorMinThumbX) * (AudioReflector.getDistanceAttenuationScalingFactor() / factorScale)); @@ -179,6 +223,123 @@ var factorThumb = Overlays.addOverlay("image", { alpha: 1 }); +var reflectiveY = topY; +topY += sliderHeight; + +var reflectiveLabel = Overlays.addOverlay("text", { + x: 40, + y: reflectiveY, + width: 60, + height: sliderHeight, + color: { red: 0, green: 0, blue: 0}, + textColor: { red: 255, green: 255, blue: 255}, + topMargin: 6, + leftMargin: 5, + text: "Reflective\nRatio:" + }); + + +var reflectiveSlider = Overlays.addOverlay("image", { + // alternate form of expressing bounds + bounds: { x: 100, y: reflectiveY, width: 150, height: sliderHeight}, + subImage: { x: 46, y: 0, width: 200, height: 71 }, + imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1 + }); + + +var reflectiveMinThumbX = 110; +var reflectiveMaxThumbX = reflectiveMinThumbX + 110; +reflectiveThumbX = reflectiveMinThumbX + ((reflectiveMaxThumbX - reflectiveMinThumbX) * AudioReflector.getReflectiveRatio()); +var reflectiveThumb = Overlays.addOverlay("image", { + x: reflectiveThumbX, + y: reflectiveY+9, + width: 18, + height: 17, + imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1 + }); + +var diffusionY = topY; +topY += sliderHeight; + +var diffusionLabel = Overlays.addOverlay("text", { + x: 40, + y: diffusionY, + width: 60, + height: sliderHeight, + color: { red: 0, green: 0, blue: 0}, + textColor: { red: 255, green: 255, blue: 255}, + topMargin: 6, + leftMargin: 5, + text: "Diffusion\nRatio:" + }); + + +var diffusionSlider = Overlays.addOverlay("image", { + // alternate form of expressing bounds + bounds: { x: 100, y: diffusionY, width: 150, height: sliderHeight}, + subImage: { x: 46, y: 0, width: 200, height: 71 }, + imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1 + }); + + +var diffusionMinThumbX = 110; +var diffusionMaxThumbX = diffusionMinThumbX + 110; +diffusionThumbX = diffusionMinThumbX + ((diffusionMaxThumbX - diffusionMinThumbX) * AudioReflector.getDiffusionRatio()); +var diffusionThumb = Overlays.addOverlay("image", { + x: diffusionThumbX, + y: diffusionY+9, + width: 18, + height: 17, + imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + color: { red: 0, green: 255, blue: 255}, + alpha: 1 + }); + +var absorptionY = topY; +topY += sliderHeight; + +var absorptionLabel = Overlays.addOverlay("text", { + x: 40, + y: absorptionY, + width: 60, + height: sliderHeight, + color: { red: 0, green: 0, blue: 0}, + textColor: { red: 255, green: 255, blue: 255}, + topMargin: 6, + leftMargin: 5, + text: "Absorption\nRatio:" + }); + + +var absorptionSlider = Overlays.addOverlay("image", { + // alternate form of expressing bounds + bounds: { x: 100, y: absorptionY, width: 150, height: sliderHeight}, + subImage: { x: 46, y: 0, width: 200, height: 71 }, + imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1 + }); + + +var absorptionMinThumbX = 110; +var absorptionMaxThumbX = absorptionMinThumbX + 110; +absorptionThumbX = absorptionMinThumbX + ((absorptionMaxThumbX - absorptionMinThumbX) * AudioReflector.getAbsorptionRatio()); +var absorptionThumb = Overlays.addOverlay("image", { + x: absorptionThumbX, + y: absorptionY+9, + width: 18, + height: 17, + imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + color: { red: 255, green: 0, blue: 255}, + alpha: 1 + }); + // When our script shuts down, we should clean up all of our overlays function scriptEnding() { @@ -197,6 +358,19 @@ function scriptEnding() { Overlays.deleteOverlay(fanoutLabel); Overlays.deleteOverlay(fanoutThumb); Overlays.deleteOverlay(fanoutSlider); + + Overlays.deleteOverlay(reflectiveLabel); + Overlays.deleteOverlay(reflectiveThumb); + Overlays.deleteOverlay(reflectiveSlider); + + Overlays.deleteOverlay(diffusionLabel); + Overlays.deleteOverlay(diffusionThumb); + Overlays.deleteOverlay(diffusionSlider); + + Overlays.deleteOverlay(absorptionLabel); + Overlays.deleteOverlay(absorptionThumb); + Overlays.deleteOverlay(absorptionSlider); + } Script.scriptEnding.connect(scriptEnding); @@ -215,6 +389,10 @@ var movingSliderDelay = false; var movingSliderFanout = false; var movingSliderSpeed = false; var movingSliderFactor = false; +var movingSliderReflective = false; +var movingSliderDiffusion = false; +var movingSliderAbsorption = false; + var thumbClickOffsetX = 0; function mouseMoveEvent(event) { if (movingSliderDelay) { @@ -227,7 +405,6 @@ function mouseMoveEvent(event) { } Overlays.editOverlay(delayThumb, { x: newThumbX } ); var delay = ((newThumbX - delayMinThumbX) / (delayMaxThumbX - delayMinThumbX)) * delayScale; - print("delay="+delay); AudioReflector.setPreDelay(delay); } if (movingSliderFanout) { @@ -240,7 +417,6 @@ function mouseMoveEvent(event) { } Overlays.editOverlay(fanoutThumb, { x: newThumbX } ); var fanout = Math.round(((newThumbX - fanoutMinThumbX) / (fanoutMaxThumbX - fanoutMinThumbX)) * fanoutScale); - print("fanout="+fanout); AudioReflector.setDiffusionFanout(fanout); } if (movingSliderSpeed) { @@ -267,47 +443,90 @@ function mouseMoveEvent(event) { var factor = ((newThumbX - factorMinThumbX) / (factorMaxThumbX - factorMinThumbX)) * factorScale; AudioReflector.setDistanceAttenuationScalingFactor(factor); } + + if (movingSliderAbsorption) { + newThumbX = event.x - thumbClickOffsetX; + if (newThumbX < absorptionMinThumbX) { + newThumbX = absorptionMminThumbX; + } + if (newThumbX > absorptionMaxThumbX) { + newThumbX = absorptionMaxThumbX; + } + Overlays.editOverlay(absorptionThumb, { x: newThumbX } ); + var absorption = ((newThumbX - absorptionMinThumbX) / (absorptionMaxThumbX - absorptionMinThumbX)) * absorptionScale; + setAbsorptionRatio(absorption); + } + + if (movingSliderReflective) { + newThumbX = event.x - thumbClickOffsetX; + if (newThumbX < reflectiveMinThumbX) { + newThumbX = reflectiveMminThumbX; + } + if (newThumbX > reflectiveMaxThumbX) { + newThumbX = reflectiveMaxThumbX; + } + Overlays.editOverlay(reflectiveThumb, { x: newThumbX } ); + var reflective = ((newThumbX - reflectiveMinThumbX) / (reflectiveMaxThumbX - reflectiveMinThumbX)) * reflectiveScale; + setReflectiveRatio(reflective); + } + + if (movingSliderDiffusion) { + newThumbX = event.x - thumbClickOffsetX; + if (newThumbX < diffusionMinThumbX) { + newThumbX = diffusionMminThumbX; + } + if (newThumbX > diffusionMaxThumbX) { + newThumbX = diffusionMaxThumbX; + } + Overlays.editOverlay(diffusionThumb, { x: newThumbX } ); + var diffusion = ((newThumbX - diffusionMinThumbX) / (diffusionMaxThumbX - diffusionMinThumbX)) * diffusionScale; + setDiffusionRatio(diffusion); + } + } // we also handle click detection in our mousePressEvent() function mousePressEvent(event) { var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); - - // If the user clicked on the thumb, handle the slider logic if (clickedOverlay == delayThumb) { movingSliderDelay = true; thumbClickOffsetX = event.x - delayThumbX; } - // If the user clicked on the thumb, handle the slider logic if (clickedOverlay == fanoutThumb) { movingSliderFanout = true; thumbClickOffsetX = event.x - fanoutThumbX; } - // If the user clicked on the thumb, handle the slider logic if (clickedOverlay == speedThumb) { movingSliderSpeed = true; thumbClickOffsetX = event.x - speedThumbX; } - - // If the user clicked on the thumb, handle the slider logic if (clickedOverlay == factorThumb) { -print("movingSliderFactor..."); movingSliderFactor = true; thumbClickOffsetX = event.x - factorThumbX; } + if (clickedOverlay == diffusionThumb) { + movingSliderDiffusion = true; + thumbClickOffsetX = event.x - diffusionThumbX; + } + if (clickedOverlay == absorptionThumb) { + movingSliderAbsorption = true; + thumbClickOffsetX = event.x - absorptionThumbX; + } + if (clickedOverlay == reflectiveThumb) { + movingSliderReflective = true; + thumbClickOffsetX = event.x - reflectiveThumbX; + } } function mouseReleaseEvent(event) { if (movingSliderDelay) { movingSliderDelay = false; var delay = ((newThumbX - delayMinThumbX) / (delayMaxThumbX - delayMinThumbX)) * delayScale; - print("delay="+delay); AudioReflector.setPreDelay(delay); delayThumbX = newThumbX; } if (movingSliderFanout) { movingSliderFanout = false; var fanout = Math.round(((newThumbX - fanoutMinThumbX) / (fanoutMaxThumbX - fanoutMinThumbX)) * fanoutScale); - print("fanout="+fanout); AudioReflector.setDiffusionFanout(fanout); fanoutThumbX = newThumbX; } @@ -323,6 +542,30 @@ function mouseReleaseEvent(event) { AudioReflector.setDistanceAttenuationScalingFactor(factor); factorThumbX = newThumbX; } + + if (movingSliderReflective) { + movingSliderReflective = false; + var reflective = ((newThumbX - reflectiveMinThumbX) / (reflectiveMaxThumbX - reflectiveMinThumbX)) * reflectiveScale; + setReflectiveRatio(reflective); + reflectiveThumbX = newThumbX; + updateRatioSliders(); + } + + if (movingSliderDiffusion) { + movingSliderDiffusion = false; + var diffusion = ((newThumbX - diffusionMinThumbX) / (diffusionMaxThumbX - diffusionMinThumbX)) * diffusionScale; + setDiffusionRatio(diffusion); + diffusionThumbX = newThumbX; + updateRatioSliders(); + } + + if (movingSliderAbsorption) { + movingSliderAbsorption = false; + var absorption = ((newThumbX - absorptionMinThumbX) / (absorptionMaxThumbX - absorptionMinThumbX)) * absorptionScale; + setAbsorptionRatio(absorption); + absorptionThumbX = newThumbX; + updateRatioSliders(); + } } Controller.mouseMoveEvent.connect(mouseMoveEvent); diff --git a/interface/src/AudioReflector.cpp b/interface/src/AudioReflector.cpp index d9dc678886..1a1c1e3b10 100644 --- a/interface/src/AudioReflector.cpp +++ b/interface/src/AudioReflector.cpp @@ -11,7 +11,6 @@ #include "AudioReflector.h" #include "Menu.h" - const float DEFAULT_PRE_DELAY = 20.0f; // this delay in msecs will always be added to all reflections const float DEFAULT_MS_DELAY_PER_METER = 3.0f; const float MINIMUM_ATTENUATION_TO_REFLECT = 1.0f / 256.0f; @@ -45,7 +44,6 @@ AudioReflector::AudioReflector(QObject* parent) : _minDelay = 0; } - void AudioReflector::render() { // if we're not set up yet, or we're not processing spatial audio, then exit early @@ -159,8 +157,11 @@ void AudioReflector::injectAudiblePoint(const AudiblePoint& audiblePoint, int rightEarDelay = rightEarDelayMsecs * sampleRate / MSECS_PER_SECOND; int leftEarDelay = leftEarDelayMsecs * sampleRate / MSECS_PER_SECOND; - float rightEarAttenuation = audiblePoint.attenuation * getDistanceAttenuationCoefficient(rightEarDistance + audiblePoint.distance); - float leftEarAttenuation = audiblePoint.attenuation * getDistanceAttenuationCoefficient(leftEarDistance + audiblePoint.distance); + float rightEarAttenuation = audiblePoint.attenuation * + getDistanceAttenuationCoefficient(rightEarDistance + audiblePoint.distance); + + float leftEarAttenuation = audiblePoint.attenuation * + getDistanceAttenuationCoefficient(leftEarDistance + audiblePoint.distance); _totalAttenuation += rightEarAttenuation + leftEarAttenuation; _attenuationCount += 2; @@ -423,7 +424,12 @@ int AudioReflector::analyzePathsSingleStep() { if (path->bounceCount > ABSOLUTE_MAXIMUM_BOUNCE_COUNT) { path->finalized = true; - } else if (_voxels->findRayIntersection(start, direction, elementHit, distance, face, Octree::Lock)) { + } else if (_voxels->findRayIntersection(start, direction, elementHit, distance, face)) { + // TODO: we need to decide how we want to handle locking on the ray intersection, if we force lock, + // we get an accurate picture, but it could prevent rendering of the voxels. If we trylock (default), + // we might not get ray intersections where they may exist, but we can't really detect that case... + // add last parameter of Octree::Lock to force locking + glm::vec3 end = start + (direction * (distance * SLIGHTLY_SHORT)); pathDistance += glm::distance(start, end); @@ -525,9 +531,15 @@ int AudioReflector::analyzePathsSingleStep() { } SurfaceCharacteristics AudioReflector::getSurfaceCharacteristics(OctreeElement* elementHit) { - float reflectiveRatio = (1.0f - (_absorptionRatio + _diffusionRatio)); - SurfaceCharacteristics result = { reflectiveRatio, _absorptionRatio, _diffusionRatio }; + SurfaceCharacteristics result = { getReflectiveRatio(), _absorptionRatio, _diffusionRatio }; return result; } +void AudioReflector::setReflectiveRatio(float ratio) { + float currentReflectiveRatio = (1.0f - (_absorptionRatio + _diffusionRatio)); + float halfDifference = (ratio - currentReflectiveRatio) / 2.0f; + // evenly distribute the difference between the two other ratios + _absorptionRatio -= halfDifference; + _diffusionRatio -= halfDifference; +} diff --git a/interface/src/AudioReflector.h b/interface/src/AudioReflector.h index 54df80e938..3a806e2267 100644 --- a/interface/src/AudioReflector.h +++ b/interface/src/AudioReflector.h @@ -84,10 +84,16 @@ public slots: void setSoundMsPerMeter(float soundMsPerMeter) { _soundMsPerMeter = soundMsPerMeter; } float getDistanceAttenuationScalingFactor() const { return _distanceAttenuationScalingFactor; } /// ms per meter, larger means slower void setDistanceAttenuationScalingFactor(float factor) { _distanceAttenuationScalingFactor = factor; } - int getDiffusionFanout() const { return _diffusionFanout; } /// number of points of diffusion from each reflection point void setDiffusionFanout(int fanout) { _diffusionFanout = fanout; } /// number of points of diffusion from each reflection point - + + float getAbsorptionRatio() const { return _absorptionRatio; } + void setAbsorptionRatio(float ratio) { _absorptionRatio = ratio; } + float getDiffusionRatio() const { return _diffusionRatio; } + void setDiffusionRatio(float ratio) { _diffusionRatio = ratio; } + float getReflectiveRatio() const { return (1.0f - (_absorptionRatio + _diffusionRatio)); } + void setReflectiveRatio(float ratio); + signals: private: diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index df47c9ad88..2b70b3538c 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -343,7 +343,7 @@ void Stats::display( lines = _expanded ? 12 : 3; if (_expanded && Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessing)) { - lines += 5; // spatial audio processing adds 1 spacing line and 4 extra lines of info + lines += 6; // spatial audio processing adds 1 spacing line and 5 extra lines of info } drawBackground(backgroundColor, horizontalOffset, 0, glWidget->width() - horizontalOffset, lines * STATS_PELS_PER_LINE + 10); @@ -541,7 +541,7 @@ void Stats::display( verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, reflectionsStatus, color); - sprintf(reflectionsStatus, "Attenuation: average %5.3f, max %5.3f, min %5.3f, distance scale: %5.3f", + sprintf(reflectionsStatus, "Attenuation: average %5.3f, max %5.3f, min %5.3f, Factor: %5.3f", audioReflector->getAverageAttenuation(), audioReflector->getMaxAttenuation(), audioReflector->getMinAttenuation(), @@ -559,6 +559,16 @@ void Stats::display( verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, reflectionsStatus, color); + const float AS_PERCENT = 100.0f; + float reflectiveRatio = audioReflector->getReflectiveRatio() * AS_PERCENT; + float diffusionRatio = audioReflector->getDiffusionRatio() * AS_PERCENT; + float absorptionRatio = audioReflector->getAbsorptionRatio() * AS_PERCENT; + sprintf(reflectionsStatus, "Ratios: Reflective: %5.3f, Diffusion: %5.3f, Absorption: %5.3f", + reflectiveRatio, diffusionRatio, absorptionRatio); + + verticalOffset += STATS_PELS_PER_LINE; + drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, reflectionsStatus, color); + } }