mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-05-29 19:01:15 +02:00
merging with upstream
This commit is contained in:
commit
3c7eb4de6d
13 changed files with 162 additions and 78 deletions
|
@ -12,6 +12,12 @@ We have a [homebrew formulas repository](https://github.com/highfidelity/homebre
|
||||||
|
|
||||||
*Our [qt5 homebrew formula](https://raw.github.com/highfidelity/homebrew-formulas/master/qt5.rb) is for a patched version of Qt 5.4.x stable that removes wireless network scanning that can reduce real-time audio performance. We recommended you use this formula to install Qt.*
|
*Our [qt5 homebrew formula](https://raw.github.com/highfidelity/homebrew-formulas/master/qt5.rb) is for a patched version of Qt 5.4.x stable that removes wireless network scanning that can reduce real-time audio performance. We recommended you use this formula to install Qt.*
|
||||||
|
|
||||||
|
###Qt
|
||||||
|
|
||||||
|
Assuming you've installed Qt 5 using the homebrew instructions above, you'll need to set QT_CMAKE_PREFIX_PATH so CMake can find your installation of Qt. For Qt 5.4.1 installed via homebrew, set QT_CMAKE_PREFIX_PATH as follows.
|
||||||
|
|
||||||
|
export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.4.1/lib/cmake
|
||||||
|
|
||||||
###Xcode
|
###Xcode
|
||||||
If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles.
|
If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles.
|
||||||
|
|
||||||
|
@ -19,4 +25,4 @@ If Xcode is your editor of choice, you can ask CMake to generate Xcode project f
|
||||||
|
|
||||||
After running cmake, you will have the make files or Xcode project file necessary to build all of the components. Open the hifi.xcodeproj file, choose ALL_BUILD from the Product > Scheme menu (or target drop down), and click Run.
|
After running cmake, you will have the make files or Xcode project file necessary to build all of the components. Open the hifi.xcodeproj file, choose ALL_BUILD from the Product > Scheme menu (or target drop down), and click Run.
|
||||||
|
|
||||||
If the build completes successfully, you will have built targets for all components located in the `build/${target_name}/Debug` directories.
|
If the build completes successfully, you will have built targets for all components located in the `build/${target_name}/Debug` directories.
|
||||||
|
|
6
cmake/externals/polyvox/CMakeLists.txt
vendored
6
cmake/externals/polyvox/CMakeLists.txt
vendored
|
@ -3,8 +3,8 @@ set(EXTERNAL_NAME polyvox)
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
ExternalProject_Add(
|
ExternalProject_Add(
|
||||||
${EXTERNAL_NAME}
|
${EXTERNAL_NAME}
|
||||||
URL http://hifi-public.s3.amazonaws.com/dependencies/polyvox-master-2015-5-27.zip
|
URL http://hifi-public.s3.amazonaws.com/dependencies/polyvox.zip
|
||||||
URL_MD5 e3dd09a24df4db29ba370e3bea753388
|
URL_MD5 904b840328278c9b36fa7a14be730c34
|
||||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||||
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
|
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
|
||||||
LOG_DOWNLOAD 1
|
LOG_DOWNLOAD 1
|
||||||
|
@ -45,7 +45,7 @@ else ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY ${INSTALL_DIR}/PolyVoxCore/lib/PolyVoxCore.lib CACHE FILEPATH "polyvox core library")
|
set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY ${INSTALL_DIR}/PolyVoxCore/lib/PolyVoxCore.lib CACHE FILEPATH "polyvox core library")
|
||||||
# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/PolyVoxUtil/lib/PolyVoxUtil.lib CACHE FILEPATH "polyvox util library")
|
# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/PolyVoxUtil/lib/PolyVoxUtil.lib CACHE FILEPATH "polyvox util library")
|
||||||
elseif (APPLE)
|
elseif (APPLE)
|
||||||
|
|
|
@ -3495,7 +3495,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("EngineRun");
|
PerformanceTimer perfTimer("EngineRun");
|
||||||
render::RenderContext renderContext;
|
render::RenderContext renderContext;
|
||||||
|
|
||||||
|
renderArgs->_shouldRender = LODManager::shouldRender;
|
||||||
|
|
||||||
renderContext.args = renderArgs;
|
renderContext.args = renderArgs;
|
||||||
renderArgs->_viewFrustum = getDisplayViewFrustum();
|
renderArgs->_viewFrustum = getDisplayViewFrustum();
|
||||||
_renderEngine->setRenderContext(renderContext);
|
_renderEngine->setRenderContext(renderContext);
|
||||||
|
|
|
@ -217,6 +217,47 @@ QString LODManager::getLODFeedbackText() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
|
||||||
|
const float maxScale = (float)TREE_SCALE;
|
||||||
|
const float octreeToMeshRatio = 4.0f; // must be this many times closer to a mesh than a voxel to see it.
|
||||||
|
float octreeSizeScale = args->_sizeScale;
|
||||||
|
int boundaryLevelAdjust = args->_boundaryLevelAdjust;
|
||||||
|
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / octreeToMeshRatio;
|
||||||
|
float distanceToCamera = glm::length(bounds.calcCenter() - args->_viewFrustum->getPosition());
|
||||||
|
float largestDimension = bounds.getLargestDimension();
|
||||||
|
|
||||||
|
static bool shouldRenderTableNeedsBuilding = true;
|
||||||
|
static QMap<float, float> shouldRenderTable;
|
||||||
|
if (shouldRenderTableNeedsBuilding) {
|
||||||
|
|
||||||
|
float SMALLEST_SCALE_IN_TABLE = 0.001f; // 1mm is plenty small
|
||||||
|
float scale = maxScale;
|
||||||
|
float factor = 1.0f;
|
||||||
|
|
||||||
|
while (scale > SMALLEST_SCALE_IN_TABLE) {
|
||||||
|
scale /= 2.0f;
|
||||||
|
factor /= 2.0f;
|
||||||
|
shouldRenderTable[scale] = factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldRenderTableNeedsBuilding = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float closestScale = maxScale;
|
||||||
|
float visibleDistanceAtClosestScale = visibleDistanceAtMaxScale;
|
||||||
|
QMap<float, float>::const_iterator lowerBound = shouldRenderTable.lowerBound(largestDimension);
|
||||||
|
if (lowerBound != shouldRenderTable.constEnd()) {
|
||||||
|
closestScale = lowerBound.key();
|
||||||
|
visibleDistanceAtClosestScale = visibleDistanceAtMaxScale * lowerBound.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closestScale < largestDimension) {
|
||||||
|
visibleDistanceAtClosestScale *= 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return distanceToCamera <= visibleDistanceAtClosestScale;
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: This is essentially the same logic used to render octree cells, but since models are more detailed then octree cells
|
// TODO: This is essentially the same logic used to render octree cells, but since models are more detailed then octree cells
|
||||||
// I've added a voxelToModelRatio that adjusts how much closer to a model you have to be to see it.
|
// I've added a voxelToModelRatio that adjusts how much closer to a model you have to be to see it.
|
||||||
bool LODManager::shouldRenderMesh(float largestDimension, float distanceToCamera) {
|
bool LODManager::shouldRenderMesh(float largestDimension, float distanceToCamera) {
|
||||||
|
|
|
@ -49,6 +49,8 @@ const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
|
||||||
// do. But both are still culled using the same angular size logic.
|
// do. But both are still culled using the same angular size logic.
|
||||||
const float AVATAR_TO_ENTITY_RATIO = 2.0f;
|
const float AVATAR_TO_ENTITY_RATIO = 2.0f;
|
||||||
|
|
||||||
|
class RenderArgs;
|
||||||
|
class AABox;
|
||||||
|
|
||||||
class LODManager : public QObject, public Dependency {
|
class LODManager : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -79,6 +81,7 @@ public:
|
||||||
Q_INVOKABLE float getLODDecreaseFPS();
|
Q_INVOKABLE float getLODDecreaseFPS();
|
||||||
Q_INVOKABLE float getLODIncreaseFPS();
|
Q_INVOKABLE float getLODIncreaseFPS();
|
||||||
|
|
||||||
|
static bool shouldRender(const RenderArgs* args, const AABox& bounds);
|
||||||
bool shouldRenderMesh(float largestDimension, float distanceToCamera);
|
bool shouldRenderMesh(float largestDimension, float distanceToCamera);
|
||||||
void autoAdjustLOD(float currentFPS);
|
void autoAdjustLOD(float currentFPS);
|
||||||
|
|
||||||
|
|
|
@ -93,22 +93,24 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
||||||
if (_isFaceTrackerConnected) {
|
if (_isFaceTrackerConnected) {
|
||||||
_blendshapeCoefficients = faceTracker->getBlendshapeCoefficients();
|
_blendshapeCoefficients = faceTracker->getBlendshapeCoefficients();
|
||||||
|
|
||||||
if (typeid(*faceTracker) == typeid(DdeFaceTracker)
|
if (typeid(*faceTracker) == typeid(DdeFaceTracker)) {
|
||||||
&& Menu::getInstance()->isOptionChecked(MenuOption::UseAudioForMouth)) {
|
|
||||||
|
|
||||||
calculateMouthShapes();
|
if (Menu::getInstance()->isOptionChecked(MenuOption::UseAudioForMouth)) {
|
||||||
|
calculateMouthShapes();
|
||||||
|
|
||||||
const int JAW_OPEN_BLENDSHAPE = 21;
|
const int JAW_OPEN_BLENDSHAPE = 21;
|
||||||
const int MMMM_BLENDSHAPE = 34;
|
const int MMMM_BLENDSHAPE = 34;
|
||||||
const int FUNNEL_BLENDSHAPE = 40;
|
const int FUNNEL_BLENDSHAPE = 40;
|
||||||
const int SMILE_LEFT_BLENDSHAPE = 28;
|
const int SMILE_LEFT_BLENDSHAPE = 28;
|
||||||
const int SMILE_RIGHT_BLENDSHAPE = 29;
|
const int SMILE_RIGHT_BLENDSHAPE = 29;
|
||||||
_blendshapeCoefficients[JAW_OPEN_BLENDSHAPE] += _audioJawOpen;
|
_blendshapeCoefficients[JAW_OPEN_BLENDSHAPE] += _audioJawOpen;
|
||||||
_blendshapeCoefficients[SMILE_LEFT_BLENDSHAPE] += _mouth4;
|
_blendshapeCoefficients[SMILE_LEFT_BLENDSHAPE] += _mouth4;
|
||||||
_blendshapeCoefficients[SMILE_RIGHT_BLENDSHAPE] += _mouth4;
|
_blendshapeCoefficients[SMILE_RIGHT_BLENDSHAPE] += _mouth4;
|
||||||
_blendshapeCoefficients[MMMM_BLENDSHAPE] += _mouth2;
|
_blendshapeCoefficients[MMMM_BLENDSHAPE] += _mouth2;
|
||||||
_blendshapeCoefficients[FUNNEL_BLENDSHAPE] += _mouth3;
|
_blendshapeCoefficients[FUNNEL_BLENDSHAPE] += _mouth3;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyEyelidOffset(getFinalOrientationInWorldFrame());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,6 +205,9 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
||||||
_mouth3,
|
_mouth3,
|
||||||
_mouth4,
|
_mouth4,
|
||||||
_blendshapeCoefficients);
|
_blendshapeCoefficients);
|
||||||
|
|
||||||
|
applyEyelidOffset(getOrientation());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_saccade = glm::vec3();
|
_saccade = glm::vec3();
|
||||||
}
|
}
|
||||||
|
@ -218,7 +223,6 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_eyePosition = calculateAverageEyePosition();
|
_eyePosition = calculateAverageEyePosition();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::calculateMouthShapes() {
|
void Head::calculateMouthShapes() {
|
||||||
|
@ -249,6 +253,32 @@ void Head::calculateMouthShapes() {
|
||||||
_mouth4 = glm::mix(_audioJawOpen, _mouth4, SMILE_PERIOD + randFloat() * SMILE_RANDOM_PERIOD);
|
_mouth4 = glm::mix(_audioJawOpen, _mouth4, SMILE_PERIOD + randFloat() * SMILE_RANDOM_PERIOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Head::applyEyelidOffset(glm::quat headOrientation) {
|
||||||
|
// Adjusts the eyelid blendshape coefficients so that the eyelid follows the iris as the head pitches.
|
||||||
|
|
||||||
|
glm::quat eyeRotation = rotationBetween(headOrientation * IDENTITY_FRONT, getCorrectedLookAtPosition() - _eyePosition);
|
||||||
|
eyeRotation = eyeRotation * glm::angleAxis(safeEulerAngles(headOrientation).y, IDENTITY_UP); // Rotation w.r.t. head
|
||||||
|
float eyePitch = safeEulerAngles(eyeRotation).x;
|
||||||
|
|
||||||
|
const float EYE_PITCH_TO_COEFFICIENT = 1.6f; // Empirically determined
|
||||||
|
const float MAX_EYELID_OFFSET = 0.8f; // So that don't fully close eyes when looking way down
|
||||||
|
float eyelidOffset = glm::clamp(-eyePitch * EYE_PITCH_TO_COEFFICIENT, -1.0f, MAX_EYELID_OFFSET);
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
const int LEFT_EYE = 8;
|
||||||
|
float eyeCoefficient = _blendshapeCoefficients[i] - _blendshapeCoefficients[LEFT_EYE + i]; // Raw value
|
||||||
|
eyeCoefficient = glm::clamp(eyelidOffset + eyeCoefficient * (1.0f - eyelidOffset), -1.0f, 1.0f);
|
||||||
|
if (eyeCoefficient > 0.0f) {
|
||||||
|
_blendshapeCoefficients[i] = eyeCoefficient;
|
||||||
|
_blendshapeCoefficients[LEFT_EYE + i] = 0.0f;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_blendshapeCoefficients[i] = 0.0f;
|
||||||
|
_blendshapeCoefficients[LEFT_EYE + i] = -eyeCoefficient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Head::relaxLean(float deltaTime) {
|
void Head::relaxLean(float deltaTime) {
|
||||||
// restore rotation, lean to neutral positions
|
// restore rotation, lean to neutral positions
|
||||||
const float LEAN_RELAXATION_PERIOD = 0.25f; // seconds
|
const float LEAN_RELAXATION_PERIOD = 0.25f; // seconds
|
||||||
|
|
|
@ -155,6 +155,7 @@ private:
|
||||||
// private methods
|
// private methods
|
||||||
void renderLookatVectors(RenderArgs* renderArgs, glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
|
void renderLookatVectors(RenderArgs* renderArgs, glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
|
||||||
void calculateMouthShapes();
|
void calculateMouthShapes();
|
||||||
|
void applyEyelidOffset(glm::quat headOrientation);
|
||||||
|
|
||||||
friend class FaceModel;
|
friend class FaceModel;
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,4 +17,10 @@ find_package(PolyVox REQUIRED)
|
||||||
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${POLYVOX_INCLUDE_DIRS})
|
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${POLYVOX_INCLUDE_DIRS})
|
||||||
target_link_libraries(${TARGET_NAME} ${POLYVOX_LIBRARIES})
|
target_link_libraries(${TARGET_NAME} ${POLYVOX_LIBRARIES})
|
||||||
|
|
||||||
|
# for changing the pitch of collision sounds
|
||||||
|
add_dependency_external_projects(soxr)
|
||||||
|
find_package(Soxr REQUIRED)
|
||||||
|
target_link_libraries(${TARGET_NAME} ${SOXR_LIBRARIES})
|
||||||
|
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${SOXR_INCLUDE_DIRS})
|
||||||
|
|
||||||
link_hifi_libraries(shared gpu script-engine render render-utils)
|
link_hifi_libraries(shared gpu script-engine render render-utils)
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include <ScriptEngine.h>
|
#include <ScriptEngine.h>
|
||||||
#include <TextureCache.h>
|
#include <TextureCache.h>
|
||||||
#include <SoundCache.h>
|
#include <SoundCache.h>
|
||||||
|
#include <soxr.h>
|
||||||
|
#include <AudioConstants.h>
|
||||||
|
|
||||||
|
|
||||||
#include "EntityTreeRenderer.h"
|
#include "EntityTreeRenderer.h"
|
||||||
|
@ -1203,7 +1205,30 @@ void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityT
|
||||||
options.stereo = sound->isStereo();
|
options.stereo = sound->isStereo();
|
||||||
options.position = position;
|
options.position = position;
|
||||||
options.volume = volume;
|
options.volume = volume;
|
||||||
AudioInjector* injector = new AudioInjector(sound.data(), options);
|
|
||||||
|
// Shift the pitch down by ln(1 + (size / COLLISION_SIZE_FOR_STANDARD_PITCH)) / ln(2)
|
||||||
|
const float COLLISION_SIZE_FOR_STANDARD_PITCH = 0.2f;
|
||||||
|
QByteArray samples = sound->getByteArray();
|
||||||
|
soxr_io_spec_t spec = soxr_io_spec(SOXR_INT16_I, SOXR_INT16_I);
|
||||||
|
soxr_quality_spec_t qualitySpec = soxr_quality_spec(SOXR_MQ, 0);
|
||||||
|
const int channelCount = sound->isStereo() ? 2 : 1;
|
||||||
|
const float factor = log(1.0f + (entity->getMaximumAACube().getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / log(2);
|
||||||
|
const int standardRate = AudioConstants::SAMPLE_RATE;
|
||||||
|
const int resampledRate = standardRate * factor;
|
||||||
|
const int nInputSamples = samples.size() / sizeof(int16_t);
|
||||||
|
const int nOutputSamples = nInputSamples * factor;
|
||||||
|
QByteArray resampled(nOutputSamples * sizeof(int16_t), '\0');
|
||||||
|
const int16_t* receivedSamples = reinterpret_cast<const int16_t*>(samples.data());
|
||||||
|
soxr_error_t soxError = soxr_oneshot(standardRate, resampledRate, channelCount,
|
||||||
|
receivedSamples, nInputSamples, NULL,
|
||||||
|
reinterpret_cast<int16_t*>(resampled.data()), nOutputSamples, NULL,
|
||||||
|
&spec, &qualitySpec, 0);
|
||||||
|
if (soxError) {
|
||||||
|
qCDebug(entitiesrenderer) << "Unable to resample" << collisionSoundURL << "from" << nInputSamples << "@" << standardRate << "to" << nOutputSamples << "@" << resampledRate;
|
||||||
|
resampled = samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioInjector* injector = new AudioInjector(resampled, options);
|
||||||
injector->setLocalAudioInterface(_localAudioInterface);
|
injector->setLocalAudioInterface(_localAudioInterface);
|
||||||
injector->triggerDeleteAfterFinish();
|
injector->triggerDeleteAfterFinish();
|
||||||
QThread* injectorThread = new QThread();
|
QThread* injectorThread = new QThread();
|
||||||
|
|
|
@ -662,7 +662,7 @@ void EntityItem::adjustEditPacketForClockSkew(unsigned char* editPacketBuffer, s
|
||||||
memcpy(&lastEditedInLocalTime, dataAt, sizeof(lastEditedInLocalTime));
|
memcpy(&lastEditedInLocalTime, dataAt, sizeof(lastEditedInLocalTime));
|
||||||
quint64 lastEditedInServerTime = lastEditedInLocalTime + clockSkew;
|
quint64 lastEditedInServerTime = lastEditedInLocalTime + clockSkew;
|
||||||
memcpy(dataAt, &lastEditedInServerTime, sizeof(lastEditedInServerTime));
|
memcpy(dataAt, &lastEditedInServerTime, sizeof(lastEditedInServerTime));
|
||||||
#if 1 //def WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
qCDebug(entities, "EntityItem::adjustEditPacketForClockSkew()...");
|
qCDebug(entities, "EntityItem::adjustEditPacketForClockSkew()...");
|
||||||
qCDebug(entities) << " lastEditedInLocalTime: " << lastEditedInLocalTime;
|
qCDebug(entities) << " lastEditedInLocalTime: " << lastEditedInLocalTime;
|
||||||
qCDebug(entities) << " clockSkew: " << clockSkew;
|
qCDebug(entities) << " clockSkew: " << clockSkew;
|
||||||
|
|
|
@ -310,10 +310,14 @@ void Model::init() {
|
||||||
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
|
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
|
||||||
modelNormalMapVertex, modelNormalSpecularMapPixel);
|
modelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||||
|
|
||||||
|
|
||||||
_renderPipelineLib.addRenderPipeline(
|
_renderPipelineLib.addRenderPipeline(
|
||||||
RenderKey(RenderKey::IS_TRANSLUCENT),
|
RenderKey(RenderKey::IS_TRANSLUCENT),
|
||||||
modelVertex, modelTranslucentPixel);
|
modelVertex, modelTranslucentPixel);
|
||||||
|
// FIXME Ignore lightmap for translucents meshpart
|
||||||
|
_renderPipelineLib.addRenderPipeline(
|
||||||
|
RenderKey(RenderKey::IS_TRANSLUCENT | RenderKey::HAS_LIGHTMAP),
|
||||||
|
modelVertex, modelTranslucentPixel);
|
||||||
|
|
||||||
_renderPipelineLib.addRenderPipeline(
|
_renderPipelineLib.addRenderPipeline(
|
||||||
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::IS_TRANSLUCENT),
|
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::IS_TRANSLUCENT),
|
||||||
|
|
|
@ -55,44 +55,6 @@ void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderCon
|
||||||
Job::~Job() {
|
Job::~Job() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
bool LODManager::shouldRenderMesh(float largestDimension, float distanceToCamera) {
|
|
||||||
const float octreeToMeshRatio = 4.0f; // must be this many times closer to a mesh than a voxel to see it.
|
|
||||||
float octreeSizeScale = getOctreeSizeScale();
|
|
||||||
int boundaryLevelAdjust = getBoundaryLevelAdjust();
|
|
||||||
float maxScale = (float)TREE_SCALE;
|
|
||||||
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / octreeToMeshRatio;
|
|
||||||
|
|
||||||
if (_shouldRenderTableNeedsRebuilding) {
|
|
||||||
_shouldRenderTable.clear();
|
|
||||||
|
|
||||||
float SMALLEST_SCALE_IN_TABLE = 0.001f; // 1mm is plenty small
|
|
||||||
float scale = maxScale;
|
|
||||||
float visibleDistanceAtScale = visibleDistanceAtMaxScale;
|
|
||||||
|
|
||||||
while (scale > SMALLEST_SCALE_IN_TABLE) {
|
|
||||||
scale /= 2.0f;
|
|
||||||
visibleDistanceAtScale /= 2.0f;
|
|
||||||
_shouldRenderTable[scale] = visibleDistanceAtScale;
|
|
||||||
}
|
|
||||||
_shouldRenderTableNeedsRebuilding = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float closestScale = maxScale;
|
|
||||||
float visibleDistanceAtClosestScale = visibleDistanceAtMaxScale;
|
|
||||||
QMap<float, float>::const_iterator lowerBound = _shouldRenderTable.lowerBound(largestDimension);
|
|
||||||
if (lowerBound != _shouldRenderTable.constEnd()) {
|
|
||||||
closestScale = lowerBound.key();
|
|
||||||
visibleDistanceAtClosestScale = lowerBound.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closestScale < largestDimension) {
|
|
||||||
visibleDistanceAtClosestScale *= 2.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (distanceToCamera <= visibleDistanceAtClosestScale);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems, ItemIDs& outItems) {
|
void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems, ItemIDs& outItems) {
|
||||||
PerformanceTimer perfTimer("cullItems");
|
PerformanceTimer perfTimer("cullItems");
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
|
@ -114,13 +76,10 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont
|
||||||
|
|
||||||
// TODO: some entity types (like lights) might want to be rendered even
|
// TODO: some entity types (like lights) might want to be rendered even
|
||||||
// when they are outside of the view frustum...
|
// when they are outside of the view frustum...
|
||||||
|
|
||||||
float distance = args->_viewFrustum->distanceToCamera(bound.calcCenter());
|
|
||||||
|
|
||||||
bool outOfView = args->_viewFrustum->boxInFrustum(bound) == ViewFrustum::OUTSIDE;
|
bool outOfView = args->_viewFrustum->boxInFrustum(bound) == ViewFrustum::OUTSIDE;
|
||||||
if (!outOfView) {
|
if (!outOfView) {
|
||||||
bool bigEnoughToRender = true; //_viewState->shouldRenderMesh(bound.getLargestDimension(), distance);
|
bool bigEnoughToRender = (args->_shouldRender) ? args->_shouldRender(args, bound) : true;
|
||||||
|
|
||||||
if (bigEnoughToRender) {
|
if (bigEnoughToRender) {
|
||||||
outItems.push_back(id); // One more Item to render
|
outItems.push_back(id); // One more Item to render
|
||||||
args->_itemsRendered++;
|
args->_itemsRendered++;
|
||||||
|
@ -130,8 +89,7 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont
|
||||||
} else {
|
} else {
|
||||||
args->_itemsOutOfView++;
|
args->_itemsOutOfView++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ItemBound {
|
struct ItemBound {
|
||||||
|
@ -144,16 +102,16 @@ struct ItemBound {
|
||||||
ItemBound(float centerDepth, float nearDepth, float farDepth, ItemID id) : _centerDepth(centerDepth), _nearDepth(nearDepth), _farDepth(farDepth), _id(id) {}
|
ItemBound(float centerDepth, float nearDepth, float farDepth, ItemID id) : _centerDepth(centerDepth), _nearDepth(nearDepth), _farDepth(farDepth), _id(id) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FrontToBackSort {
|
struct FrontToBackSort {
|
||||||
bool operator() (const ItemBound& left, const ItemBound& right) {
|
bool operator() (const ItemBound& left, const ItemBound& right) {
|
||||||
return (left._centerDepth < right._centerDepth);
|
return (left._centerDepth < right._centerDepth);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BackToFrontSort {
|
struct BackToFrontSort {
|
||||||
bool operator() (const ItemBound& left, const ItemBound& right) {
|
bool operator() (const ItemBound& left, const ItemBound& right) {
|
||||||
return (left._centerDepth > right._centerDepth);
|
return (left._centerDepth > right._centerDepth);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDs& inItems, ItemIDs& outItems) {
|
void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDs& inItems, ItemIDs& outItems) {
|
||||||
|
|
|
@ -12,8 +12,11 @@
|
||||||
#ifndef hifi_RenderArgs_h
|
#ifndef hifi_RenderArgs_h
|
||||||
#define hifi_RenderArgs_h
|
#define hifi_RenderArgs_h
|
||||||
|
|
||||||
class ViewFrustum;
|
#include <functional>
|
||||||
|
|
||||||
|
class AABox;
|
||||||
class OctreeRenderer;
|
class OctreeRenderer;
|
||||||
|
class ViewFrustum;
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
class Batch;
|
class Batch;
|
||||||
class Context;
|
class Context;
|
||||||
|
@ -21,6 +24,8 @@ class Context;
|
||||||
|
|
||||||
class RenderArgs {
|
class RenderArgs {
|
||||||
public:
|
public:
|
||||||
|
typedef std::function<bool(const RenderArgs* args, const AABox& bounds)> ShoudRenderFunctor;
|
||||||
|
|
||||||
enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE, MIRROR_RENDER_MODE };
|
enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE, MIRROR_RENDER_MODE };
|
||||||
|
|
||||||
enum RenderSide { MONO, STEREO_LEFT, STEREO_RIGHT };
|
enum RenderSide { MONO, STEREO_LEFT, STEREO_RIGHT };
|
||||||
|
@ -40,6 +45,7 @@ public:
|
||||||
RenderSide renderSide = MONO,
|
RenderSide renderSide = MONO,
|
||||||
DebugFlags debugFlags = RENDER_DEBUG_NONE,
|
DebugFlags debugFlags = RENDER_DEBUG_NONE,
|
||||||
gpu::Batch* batch = nullptr,
|
gpu::Batch* batch = nullptr,
|
||||||
|
ShoudRenderFunctor shouldRender = nullptr,
|
||||||
|
|
||||||
int elementsTouched = 0,
|
int elementsTouched = 0,
|
||||||
int itemsRendered = 0,
|
int itemsRendered = 0,
|
||||||
|
@ -66,6 +72,7 @@ public:
|
||||||
_renderSide(renderSide),
|
_renderSide(renderSide),
|
||||||
_debugFlags(debugFlags),
|
_debugFlags(debugFlags),
|
||||||
_batch(batch),
|
_batch(batch),
|
||||||
|
_shouldRender(shouldRender),
|
||||||
|
|
||||||
_elementsTouched(elementsTouched),
|
_elementsTouched(elementsTouched),
|
||||||
_itemsRendered(itemsRendered),
|
_itemsRendered(itemsRendered),
|
||||||
|
@ -94,6 +101,7 @@ public:
|
||||||
RenderSide _renderSide;
|
RenderSide _renderSide;
|
||||||
DebugFlags _debugFlags;
|
DebugFlags _debugFlags;
|
||||||
gpu::Batch* _batch;
|
gpu::Batch* _batch;
|
||||||
|
ShoudRenderFunctor _shouldRender;
|
||||||
|
|
||||||
int _elementsTouched;
|
int _elementsTouched;
|
||||||
int _itemsRendered;
|
int _itemsRendered;
|
||||||
|
|
Loading…
Reference in a new issue