Merge branch 'master' of https://github.com/highfidelity/hifi into orange

This commit is contained in:
Sam Gateau 2015-04-17 13:04:00 -07:00
commit 11879f6142
10 changed files with 182 additions and 380 deletions

View file

@ -1748,7 +1748,10 @@ void Application::setActiveFaceTracker() {
DependencyManager::get<Faceshift>()->setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift));
#endif
#ifdef HAVE_DDE
DependencyManager::get<DdeFaceTracker>()->setEnabled(Menu::getInstance()->isOptionChecked(MenuOption::DDEFaceRegression));
bool isUsingDDE = Menu::getInstance()->isOptionChecked(MenuOption::DDEFaceRegression);
Menu::getInstance()->getActionForOption(MenuOption::DDEFiltering)->setVisible(isUsingDDE);
Menu::getInstance()->getActionForOption(MenuOption::ResetDDETracking)->setVisible(isUsingDDE);
DependencyManager::get<DdeFaceTracker>()->setEnabled(isUsingDDE);
#endif
#ifdef HAVE_VISAGE
DependencyManager::get<Visage>()->updateEnabled();

View file

@ -210,7 +210,6 @@ public:
bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; }
FaceTracker* getActiveFaceTracker();
void setActiveFaceTracker();
QSystemTrayIcon* getTrayIcon() { return _trayIcon; }
ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; }
@ -385,6 +384,8 @@ public slots:
void setVSyncEnabled();
void resetSensors();
void setActiveFaceTracker();
void aboutApp();
void showEditEntitiesHelp();

View file

@ -362,30 +362,32 @@ Menu::Menu() {
QAction* noFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::NoFaceTracking,
0, true,
this, SLOT(setActiveFaceTracker()));
qApp, SLOT(setActiveFaceTracker()));
faceTrackerGroup->addAction(noFaceTracker);
#ifdef HAVE_FACESHIFT
QAction* faceshiftFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::Faceshift,
0, false,
this, SLOT(setActiveFaceTracker()));
qApp, SLOT(setActiveFaceTracker()));
faceTrackerGroup->addAction(faceshiftFaceTracker);
#endif
#ifdef HAVE_DDE
QAction* ddeFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::DDEFaceRegression,
0, false,
this, SLOT(setActiveFaceTracker()));
qApp, SLOT(setActiveFaceTracker()));
faceTrackerGroup->addAction(ddeFaceTracker);
#endif
#ifdef HAVE_VISAGE
QAction* visageFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::Visage,
0, false,
this, SLOT(setActiveFaceTracker()));
qApp, SLOT(setActiveFaceTracker()));
faceTrackerGroup->addAction(visageFaceTracker);
#endif
}
#ifdef HAVE_DDE
faceTrackingMenu->addSeparator();
QAction* ddeFiltering = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::DDEFiltering, 0, true);
ddeFiltering->setVisible(false);
QAction* ddeFaceTrackerReset = addActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::ResetDDETracking,
Qt::CTRL | Qt::Key_Apostrophe,
DependencyManager::get<DdeFaceTracker>().data(), SLOT(resetTracking()));
@ -987,11 +989,3 @@ void Menu::visibilityChanged(Discoverability::Mode discoverabilityMode) {
qCDebug(interfaceapp) << "ERROR Menu::visibilityChanged() called with unrecognized value.";
}
}
void Menu::setActiveFaceTracker() {
#ifdef HAVE_DDE
bool isUsingDDE = Menu::getInstance()->isOptionChecked(MenuOption::DDEFaceRegression);
Menu::getInstance()->getActionForOption(MenuOption::ResetDDETracking)->setVisible(isUsingDDE);
#endif
qApp->setActiveFaceTracker();
}

View file

@ -68,7 +68,6 @@ public slots:
private slots:
void setVisibility();
void setActiveFaceTracker();
private:
static Menu* _instance;
@ -137,6 +136,7 @@ namespace MenuOption {
const QString CopyAddress = "Copy Address to Clipboard";
const QString CopyPath = "Copy Path to Clipboard";
const QString DDEFaceRegression = "DDE Face Regression";
const QString DDEFiltering = "DDE Filtering";
const QString DecreaseAvatarSize = "Decrease Avatar Size";
const QString DeleteBookmark = "Delete Bookmark...";
const QString DisableActivityLogger = "Disable Activity Logger";

View file

@ -17,6 +17,8 @@
#include <QJsonObject>
#include <QElapsedTimer>
#include <GLMHelpers.h>
#include "DdeFaceTracker.h"
#include "FaceshiftConstants.h"
#include "InterfaceLogging.h"
@ -27,9 +29,9 @@ static const QHostAddress DDE_SERVER_ADDR("127.0.0.1");
static const quint16 DDE_SERVER_PORT = 64204;
static const quint16 DDE_CONTROL_PORT = 64205;
#if defined(Q_OS_WIN)
static const QString DDE_PROGRAM_PATH = QCoreApplication::applicationDirPath() + "/dde/dde.exe";
static const QString DDE_PROGRAM_PATH = "/dde/dde.exe";
#elif defined(Q_OS_MAC)
static const QString DDE_PROGRAM_PATH = QCoreApplication::applicationDirPath() + "/dde.app/Contents/MacOS/dde";
static const QString DDE_PROGRAM_PATH = "/dde.app/Contents/MacOS/dde";
#endif
static const QStringList DDE_ARGUMENTS = QStringList()
<< "--udp=" + DDE_SERVER_ADDR.toString() + ":" + QString::number(DDE_SERVER_PORT)
@ -132,6 +134,8 @@ struct Packet {
char name[MAX_NAME_SIZE + 1];
};
const float STARTING_DDE_MESSAGE_TIME = 0.033f;
DdeFaceTracker::DdeFaceTracker() :
DdeFaceTracker(QHostAddress::Any, DDE_SERVER_PORT, DDE_CONTROL_PORT)
{
@ -157,11 +161,16 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui
_mouthSmileLeftIndex(28),
_mouthSmileRightIndex(29),
_jawOpenIndex(21),
_previousTranslation(glm::vec3()),
_previousRotation(glm::quat())
_lastMessageReceived(0),
_averageMessageTime(STARTING_DDE_MESSAGE_TIME),
_lastHeadTranslation(glm::vec3(0.0f)),
_filteredHeadTranslation(glm::vec3(0.0f)),
_lastLeftEyeBlink(0.0f),
_filteredLeftEyeBlink(0.0f),
_lastRightEyeBlink(0.0f),
_filteredRightEyeBlink(0.0f)
{
_coefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
_previousCoefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
_blendshapeCoefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
@ -272,6 +281,8 @@ float DdeFaceTracker::getBlendshapeCoefficient(int index) const {
void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
if(buffer.size() > MIN_PACKET_SIZE) {
bool isFiltering = Menu::getInstance()->isOptionChecked(MenuOption::DDEFiltering);
Packet packet;
int bytesToCopy = glm::min((int)sizeof(packet), buffer.size());
memset(&packet.name, '\n', MAX_NAME_SIZE + 1);
@ -292,13 +303,36 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
translation -= _referenceTranslation;
translation /= LEAN_DAMPING_FACTOR;
translation.x *= -1;
_headTranslation = (translation + _previousTranslation) / 2.0f;
_previousTranslation = translation;
if (isFiltering) {
glm::vec3 linearVelocity = (translation - _lastHeadTranslation) / _averageMessageTime;
const float LINEAR_VELOCITY_FILTER_STRENGTH = 0.3f;
float velocityFilter = glm::clamp(1.0f - glm::length(linearVelocity) *
LINEAR_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
_filteredHeadTranslation = velocityFilter * _filteredHeadTranslation + (1.0f - velocityFilter) * translation;
_lastHeadTranslation = translation;
_headTranslation = _filteredHeadTranslation;
} else {
_headTranslation = translation;
}
// Compute relative rotation
rotation = glm::inverse(_referenceRotation) * rotation;
_headRotation = (rotation + _previousRotation) / 2.0f;
_previousRotation = rotation;
if (isFiltering) {
glm::quat r = rotation * glm::inverse(_headRotation);
float theta = 2 * acos(r.w);
glm::vec3 angularVelocity;
if (theta > EPSILON) {
float rMag = glm::length(glm::vec3(r.x, r.y, r.z));
angularVelocity = theta / _averageMessageTime * glm::vec3(r.x, r.y, r.z) / rMag;
} else {
angularVelocity = glm::vec3(0, 0, 0);
}
const float ANGULAR_VELOCITY_FILTER_STRENGTH = 0.3f;
_headRotation = safeMix(_headRotation, rotation, glm::clamp(glm::length(angularVelocity) *
ANGULAR_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f));
} else {
_headRotation = rotation;
}
// Translate DDE coefficients to Faceshift compatible coefficients
for (int i = 0; i < NUM_EXPRESSIONS; i += 1) {
@ -307,8 +341,23 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
// Use EyeBlink values to control both EyeBlink and EyeOpen
static const float RELAXED_EYE_VALUE = 0.1f;
float leftEye = (_coefficients[_leftBlinkIndex] + _previousCoefficients[_leftBlinkIndex]) / 2.0f;
float rightEye = (_coefficients[_rightBlinkIndex] + _previousCoefficients[_rightBlinkIndex]) / 2.0f;
float leftEye = _coefficients[_leftBlinkIndex];
float rightEye = _coefficients[_rightBlinkIndex];
if (isFiltering) {
const float BLINK_VELOCITY_FILTER_STRENGTH = 0.3f;
float velocity = fabs(leftEye - _lastLeftEyeBlink) / _averageMessageTime;
float velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
_filteredLeftEyeBlink = velocityFilter * leftEye + (1.0f - velocityFilter) * _filteredLeftEyeBlink;
_lastLeftEyeBlink = leftEye;
leftEye = _filteredLeftEyeBlink;
velocity = fabs(rightEye - _lastRightEyeBlink) / _averageMessageTime;
velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
_filteredRightEyeBlink = velocityFilter * rightEye + (1.0f - velocityFilter) * _filteredRightEyeBlink;
_lastRightEyeBlink = rightEye;
rightEye = _filteredRightEyeBlink;
}
if (leftEye > RELAXED_EYE_VALUE) {
_coefficients[_leftBlinkIndex] = leftEye - RELAXED_EYE_VALUE;
_coefficients[_leftEyeOpenIndex] = 0.0f;
@ -343,10 +392,18 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
// Scale all coefficients
for (int i = 0; i < NUM_EXPRESSIONS; i += 1) {
_blendshapeCoefficients[i]
= glm::clamp(DDE_COEFFICIENT_SCALES[i] * (_coefficients[i] + _previousCoefficients[i]) / 2.0f, 0.0f, 1.0f);
_previousCoefficients[i] = _coefficients[i];
= glm::clamp(DDE_COEFFICIENT_SCALES[i] * _coefficients[i], 0.0f, 1.0f);
}
// Calculate average frame time
const float FRAME_AVERAGING_FACTOR = 0.99f;
quint64 usecsNow = usecTimestampNow();
if (_lastMessageReceived != 0) {
_averageMessageTime = FRAME_AVERAGING_FACTOR * _averageMessageTime
+ (1.0f - FRAME_AVERAGING_FACTOR) * (float)(usecsNow - _lastMessageReceived) / 1000000.0f;
}
_lastMessageReceived = usecsNow;
} else {
qCDebug(interfaceapp) << "[Error] DDE Face Tracker Decode Error";
}

View file

@ -101,10 +101,14 @@ private:
QVector<float> _coefficients;
// Previous values for simple smoothing
glm::vec3 _previousTranslation;
glm::quat _previousRotation;
QVector<float> _previousCoefficients;
quint64 _lastMessageReceived;
float _averageMessageTime;
glm::vec3 _lastHeadTranslation;
glm::vec3 _filteredHeadTranslation;
float _lastLeftEyeBlink;
float _filteredLeftEyeBlink;
float _lastRightEyeBlink;
float _filteredRightEyeBlink;
};
#endif // hifi_DdeFaceTracker_h

View file

@ -1705,7 +1705,12 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
material._material->setDiffuse(material.diffuse);
material._material->setSpecular(material.specular);
material._material->setShininess(material.shininess);
material._material->setOpacity(material.opacity);
if (material.opacity <= 0.0f) {
material._material->setOpacity(1.0f);
} else {
material._material->setOpacity(material.opacity);
}
materials.insert(material.id, material);

View file

@ -12,4 +12,16 @@ add_dependency_external_projects(glm)
find_package(GLM REQUIRED)
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
if (WIN32)
if (USE_NSIGHT)
# try to find the Nsight package and add it to the build if we find it
find_package(NSIGHT)
if (NSIGHT_FOUND)
include_directories(${NSIGHT_INCLUDE_DIRS})
add_definitions(-DNSIGHT_FOUND)
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
endif ()
endif()
endif (WIN32)
link_hifi_libraries(animation fbx shared gpu)

View file

@ -244,13 +244,6 @@ void Model::initJointTransforms() {
void Model::init() {
if (_renderPipelineLib.empty()) {
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), 0));
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1));
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2));
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), 3));
// Vertex shaders
auto modelVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_vert)));
auto modelNormalMapVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_normal_map_vert)));
@ -291,10 +284,24 @@ void Model::init() {
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
modelNormalMapVertex, modelNormalSpecularMapPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_TRANSLUCENT),
modelVertex, modelTranslucentPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::IS_TRANSLUCENT),
modelNormalMapVertex, modelTranslucentPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT),
modelVertex, modelTranslucentPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT),
modelNormalMapVertex, modelTranslucentPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_LIGHTMAP),
modelLightmapVertex, modelLightmapPixel);
@ -310,6 +317,7 @@ void Model::init() {
RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED),
skinModelVertex, modelPixel);
@ -326,15 +334,29 @@ void Model::init() {
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_TRANSLUCENT),
skinModelVertex, modelTranslucentPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::IS_TRANSLUCENT),
skinModelNormalMapVertex, modelTranslucentPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT),
skinModelVertex, modelTranslucentPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT),
skinModelNormalMapVertex, modelTranslucentPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_DEPTH_ONLY | RenderKey::IS_SHADOW),
modelShadowVertex, modelShadowPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_DEPTH_ONLY | RenderKey::IS_SHADOW),
skinModelShadowVertex, modelShadowPixel);
@ -1935,55 +1957,7 @@ bool Model::renderInScene(float alpha, RenderArgs* args) {
}
void Model::segregateMeshGroups() {
_meshesTranslucentTangents.clear();
_meshesTranslucent.clear();
_meshesTranslucentTangentsSpecular.clear();
_meshesTranslucentSpecular.clear();
_meshesTranslucentTangentsSkinned.clear();
_meshesTranslucentSkinned.clear();
_meshesTranslucentTangentsSpecularSkinned.clear();
_meshesTranslucentSpecularSkinned.clear();
_meshesOpaqueTangents.clear();
_meshesOpaque.clear();
_meshesOpaqueTangentsSpecular.clear();
_meshesOpaqueSpecular.clear();
_meshesOpaqueTangentsSkinned.clear();
_meshesOpaqueSkinned.clear();
_meshesOpaqueTangentsSpecularSkinned.clear();
_meshesOpaqueSpecularSkinned.clear();
_meshesOpaqueLightmapTangents.clear();
_meshesOpaqueLightmap.clear();
_meshesOpaqueLightmapTangentsSpecular.clear();
_meshesOpaqueLightmapSpecular.clear();
_unsortedMeshesTranslucentTangents.clear();
_unsortedMeshesTranslucent.clear();
_unsortedMeshesTranslucentTangentsSpecular.clear();
_unsortedMeshesTranslucentSpecular.clear();
_unsortedMeshesTranslucentTangentsSkinned.clear();
_unsortedMeshesTranslucentSkinned.clear();
_unsortedMeshesTranslucentTangentsSpecularSkinned.clear();
_unsortedMeshesTranslucentSpecularSkinned.clear();
_unsortedMeshesOpaqueTangents.clear();
_unsortedMeshesOpaque.clear();
_unsortedMeshesOpaqueTangentsSpecular.clear();
_unsortedMeshesOpaqueSpecular.clear();
_unsortedMeshesOpaqueTangentsSkinned.clear();
_unsortedMeshesOpaqueSkinned.clear();
_unsortedMeshesOpaqueTangentsSpecularSkinned.clear();
_unsortedMeshesOpaqueSpecularSkinned.clear();
_unsortedMeshesOpaqueLightmapTangents.clear();
_unsortedMeshesOpaqueLightmap.clear();
_unsortedMeshesOpaqueLightmapTangentsSpecular.clear();
_unsortedMeshesOpaqueLightmapSpecular.clear();
_renderBuckets.clear();
const FBXGeometry& geometry = _geometry->getFBXGeometry();
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
@ -2017,201 +1991,19 @@ void Model::segregateMeshGroups() {
qCDebug(renderutils) << "materialID:" << materialID << "parts:" << mesh.parts.size();
}
if (!hasLightmap) {
if (translucentMesh && !hasTangents && !hasSpecular && !isSkinned) {
RenderKey key(translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned);
_unsortedMeshesTranslucent.insertMulti(materialID, i);
} else if (translucentMesh && hasTangents && !hasSpecular && !isSkinned) {
_unsortedMeshesTranslucentTangents.insertMulti(materialID, i);
} else if (translucentMesh && hasTangents && hasSpecular && !isSkinned) {
_unsortedMeshesTranslucentTangentsSpecular.insertMulti(materialID, i);
} else if (translucentMesh && !hasTangents && hasSpecular && !isSkinned) {
_unsortedMeshesTranslucentSpecular.insertMulti(materialID, i);
} else if (translucentMesh && hasTangents && !hasSpecular && isSkinned) {
_unsortedMeshesTranslucentTangentsSkinned.insertMulti(materialID, i);
} else if (translucentMesh && !hasTangents && !hasSpecular && isSkinned) {
_unsortedMeshesTranslucentSkinned.insertMulti(materialID, i);
} else if (translucentMesh && hasTangents && hasSpecular && isSkinned) {
_unsortedMeshesTranslucentTangentsSpecularSkinned.insertMulti(materialID, i);
} else if (translucentMesh && !hasTangents && hasSpecular && isSkinned) {
_unsortedMeshesTranslucentSpecularSkinned.insertMulti(materialID, i);
} else if (!translucentMesh && !hasTangents && !hasSpecular && !isSkinned) {
_unsortedMeshesOpaque.insertMulti(materialID, i);
} else if (!translucentMesh && hasTangents && !hasSpecular && !isSkinned) {
_unsortedMeshesOpaqueTangents.insertMulti(materialID, i);
} else if (!translucentMesh && hasTangents && hasSpecular && !isSkinned) {
_unsortedMeshesOpaqueTangentsSpecular.insertMulti(materialID, i);
} else if (!translucentMesh && !hasTangents && hasSpecular && !isSkinned) {
_unsortedMeshesOpaqueSpecular.insertMulti(materialID, i);
} else if (!translucentMesh && hasTangents && !hasSpecular && isSkinned) {
_unsortedMeshesOpaqueTangentsSkinned.insertMulti(materialID, i);
} else if (!translucentMesh && !hasTangents && !hasSpecular && isSkinned) {
_unsortedMeshesOpaqueSkinned.insertMulti(materialID, i);
} else if (!translucentMesh && hasTangents && hasSpecular && isSkinned) {
_unsortedMeshesOpaqueTangentsSpecularSkinned.insertMulti(materialID, i);
} else if (!translucentMesh && !hasTangents && hasSpecular && isSkinned) {
_unsortedMeshesOpaqueSpecularSkinned.insertMulti(materialID, i);
} else {
qCDebug(renderutils) << "unexpected!!! this mesh didn't fall into any or our groups???";
}
} else {
if (!translucentMesh && !hasTangents && !hasSpecular && !isSkinned) {
_unsortedMeshesOpaqueLightmap.insertMulti(materialID, i);
} else if (!translucentMesh && hasTangents && !hasSpecular && !isSkinned) {
_unsortedMeshesOpaqueLightmapTangents.insertMulti(materialID, i);
} else if (!translucentMesh && hasTangents && hasSpecular && !isSkinned) {
_unsortedMeshesOpaqueLightmapTangentsSpecular.insertMulti(materialID, i);
} else if (!translucentMesh && !hasTangents && hasSpecular && !isSkinned) {
_unsortedMeshesOpaqueLightmapSpecular.insertMulti(materialID, i);
} else {
qCDebug(renderutils) << "unexpected!!! this mesh didn't fall into any or our groups???";
}
}
// reuse or create the bucket corresponding to that key and insert the mesh as unsorted
_renderBuckets[key.getRaw()]._unsortedMeshes.insertMulti(materialID, i);
}
foreach(int i, _unsortedMeshesTranslucent) {
_meshesTranslucent.append(i);
for(auto& b : _renderBuckets) {
foreach(auto i, b.second._unsortedMeshes) {
b.second._meshes.append(i);
b.second._unsortedMeshes.clear();
}
}
foreach(int i, _unsortedMeshesTranslucentTangents) {
_meshesTranslucentTangents.append(i);
}
foreach(int i, _unsortedMeshesTranslucentTangentsSpecular) {
_meshesTranslucentTangentsSpecular.append(i);
}
foreach(int i, _unsortedMeshesTranslucentSpecular) {
_meshesTranslucentSpecular.append(i);
}
foreach(int i, _unsortedMeshesTranslucentSkinned) {
_meshesTranslucentSkinned.append(i);
}
foreach(int i, _unsortedMeshesTranslucentTangentsSkinned) {
_meshesTranslucentTangentsSkinned.append(i);
}
foreach(int i, _unsortedMeshesTranslucentTangentsSpecularSkinned) {
_meshesTranslucentTangentsSpecularSkinned.append(i);
}
foreach(int i, _unsortedMeshesTranslucentSpecularSkinned) {
_meshesTranslucentSpecularSkinned.append(i);
}
foreach(int i, _unsortedMeshesOpaque) {
_meshesOpaque.append(i);
}
foreach(int i, _unsortedMeshesOpaqueTangents) {
_meshesOpaqueTangents.append(i);
}
foreach(int i, _unsortedMeshesOpaqueTangentsSpecular) {
_meshesOpaqueTangentsSpecular.append(i);
}
foreach(int i, _unsortedMeshesOpaqueSpecular) {
_meshesOpaqueSpecular.append(i);
}
foreach(int i, _unsortedMeshesOpaqueSkinned) {
_meshesOpaqueSkinned.append(i);
}
foreach(int i, _unsortedMeshesOpaqueTangentsSkinned) {
_meshesOpaqueTangentsSkinned.append(i);
}
foreach(int i, _unsortedMeshesOpaqueTangentsSpecularSkinned) {
_meshesOpaqueTangentsSpecularSkinned.append(i);
}
foreach(int i, _unsortedMeshesOpaqueSpecularSkinned) {
_meshesOpaqueSpecularSkinned.append(i);
}
foreach(int i, _unsortedMeshesOpaqueLightmap) {
_meshesOpaqueLightmap.append(i);
}
foreach(int i, _unsortedMeshesOpaqueLightmapTangents) {
_meshesOpaqueLightmapTangents.append(i);
}
foreach(int i, _unsortedMeshesOpaqueLightmapTangentsSpecular) {
_meshesOpaqueLightmapTangentsSpecular.append(i);
}
foreach(int i, _unsortedMeshesOpaqueLightmapSpecular) {
_meshesOpaqueLightmapSpecular.append(i);
}
_unsortedMeshesTranslucentTangents.clear();
_unsortedMeshesTranslucent.clear();
_unsortedMeshesTranslucentTangentsSpecular.clear();
_unsortedMeshesTranslucentSpecular.clear();
_unsortedMeshesTranslucentTangentsSkinned.clear();
_unsortedMeshesTranslucentSkinned.clear();
_unsortedMeshesTranslucentTangentsSpecularSkinned.clear();
_unsortedMeshesTranslucentSpecularSkinned.clear();
_unsortedMeshesOpaqueTangents.clear();
_unsortedMeshesOpaque.clear();
_unsortedMeshesOpaqueTangentsSpecular.clear();
_unsortedMeshesOpaqueSpecular.clear();
_unsortedMeshesOpaqueTangentsSkinned.clear();
_unsortedMeshesOpaqueSkinned.clear();
_unsortedMeshesOpaqueTangentsSpecularSkinned.clear();
_unsortedMeshesOpaqueSpecularSkinned.clear();
_unsortedMeshesOpaqueLightmapTangents.clear();
_unsortedMeshesOpaqueLightmap.clear();
_unsortedMeshesOpaqueLightmapTangentsSpecular.clear();
_unsortedMeshesOpaqueLightmapSpecular.clear();
_meshGroupsKnown = true;
}
@ -2220,52 +2012,14 @@ QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool h
// depending on which parameters we were called with, pick the correct mesh group to render
QVector<int>* whichList = NULL;
if (translucent && !hasTangents && !hasSpecular && !isSkinned) {
whichList = &_meshesTranslucent;
} else if (translucent && hasTangents && !hasSpecular && !isSkinned) {
whichList = &_meshesTranslucentTangents;
} else if (translucent && hasTangents && hasSpecular && !isSkinned) {
whichList = &_meshesTranslucentTangentsSpecular;
} else if (translucent && !hasTangents && hasSpecular && !isSkinned) {
whichList = &_meshesTranslucentSpecular;
} else if (translucent && hasTangents && !hasSpecular && isSkinned) {
whichList = &_meshesTranslucentTangentsSkinned;
} else if (translucent && !hasTangents && !hasSpecular && isSkinned) {
whichList = &_meshesTranslucentSkinned;
} else if (translucent && hasTangents && hasSpecular && isSkinned) {
whichList = &_meshesTranslucentTangentsSpecularSkinned;
} else if (translucent && !hasTangents && hasSpecular && isSkinned) {
whichList = &_meshesTranslucentSpecularSkinned;
} else if (!translucent && !hasLightmap && !hasTangents && !hasSpecular && !isSkinned) {
whichList = &_meshesOpaque;
} else if (!translucent && !hasLightmap && hasTangents && !hasSpecular && !isSkinned) {
whichList = &_meshesOpaqueTangents;
} else if (!translucent && !hasLightmap && hasTangents && hasSpecular && !isSkinned) {
whichList = &_meshesOpaqueTangentsSpecular;
} else if (!translucent && !hasLightmap && !hasTangents && hasSpecular && !isSkinned) {
whichList = &_meshesOpaqueSpecular;
} else if (!translucent && !hasLightmap && hasTangents && !hasSpecular && isSkinned) {
whichList = &_meshesOpaqueTangentsSkinned;
} else if (!translucent && !hasLightmap && !hasTangents && !hasSpecular && isSkinned) {
whichList = &_meshesOpaqueSkinned;
} else if (!translucent && !hasLightmap && hasTangents && hasSpecular && isSkinned) {
whichList = &_meshesOpaqueTangentsSpecularSkinned;
} else if (!translucent && !hasLightmap && !hasTangents && hasSpecular && isSkinned) {
whichList = &_meshesOpaqueSpecularSkinned;
RenderKey key(translucent, hasLightmap, hasTangents, hasSpecular, isSkinned);
} else if (!translucent && hasLightmap && !hasTangents && !hasSpecular && !isSkinned) {
whichList = &_meshesOpaqueLightmap;
} else if (!translucent && hasLightmap && hasTangents && !hasSpecular && !isSkinned) {
whichList = &_meshesOpaqueLightmapTangents;
} else if (!translucent && hasLightmap && hasTangents && hasSpecular && !isSkinned) {
whichList = &_meshesOpaqueLightmapTangentsSpecular;
} else if (!translucent && hasLightmap && !hasTangents && hasSpecular && !isSkinned) {
whichList = &_meshesOpaqueLightmapSpecular;
} else {
qCDebug(renderutils) << "unexpected!!! this mesh didn't fall into any or our groups???";
auto bucket = _renderBuckets.find(key.getRaw());
if (bucket != _renderBuckets.end()) {
whichList = &(*bucket).second._meshes;
}
return whichList;
}
@ -2277,6 +2031,7 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
auto pipeline = _renderPipelineLib.find(key.getRaw());
if (pipeline == _renderPipelineLib.end()) {
qDebug() << "No good, couldn't find a pipeline from the key ?" << key.getRaw();
locations = 0;
return;
}
@ -2303,7 +2058,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
int meshPartsRendered = 0;
bool pickProgramsNeeded = true;
Locations* locations;
Locations* locations = nullptr;
foreach(Model* model, _modelsInScene) {
QVector<int>* whichList = model->pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
@ -2331,20 +2086,19 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
PROFILE_RANGE(__FUNCTION__);
int meshPartsRendered = 0;
QVector<int>* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
//Pick the mesh list with the requested render flags
QVector<int>* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
if (!whichList) {
qCDebug(renderutils) << "unexpected!!! we don't know which list of meshes to render...";
return 0;
}
QVector<int>& list = *whichList;
// If this list has nothing to render, then don't bother proceeding. This saves us on binding to programs
if (list.size() == 0) {
if (list.empty()) {
return 0;
}
Locations* locations;
Locations* locations = nullptr;
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned,
args, locations);
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,

View file

@ -350,58 +350,6 @@ private:
bool _meshGroupsKnown;
QMap<QString, int> _unsortedMeshesTranslucent;
QMap<QString, int> _unsortedMeshesTranslucentTangents;
QMap<QString, int> _unsortedMeshesTranslucentTangentsSpecular;
QMap<QString, int> _unsortedMeshesTranslucentSpecular;
QMap<QString, int> _unsortedMeshesTranslucentSkinned;
QMap<QString, int> _unsortedMeshesTranslucentTangentsSkinned;
QMap<QString, int> _unsortedMeshesTranslucentTangentsSpecularSkinned;
QMap<QString, int> _unsortedMeshesTranslucentSpecularSkinned;
QMap<QString, int> _unsortedMeshesOpaque;
QMap<QString, int> _unsortedMeshesOpaqueTangents;
QMap<QString, int> _unsortedMeshesOpaqueTangentsSpecular;
QMap<QString, int> _unsortedMeshesOpaqueSpecular;
QMap<QString, int> _unsortedMeshesOpaqueSkinned;
QMap<QString, int> _unsortedMeshesOpaqueTangentsSkinned;
QMap<QString, int> _unsortedMeshesOpaqueTangentsSpecularSkinned;
QMap<QString, int> _unsortedMeshesOpaqueSpecularSkinned;
QMap<QString, int> _unsortedMeshesOpaqueLightmap;
QMap<QString, int> _unsortedMeshesOpaqueLightmapTangents;
QMap<QString, int> _unsortedMeshesOpaqueLightmapTangentsSpecular;
QMap<QString, int> _unsortedMeshesOpaqueLightmapSpecular;
typedef std::unordered_map<int, QVector<int>> MeshListMap;
MeshListMap _sortedMeshes;
QVector<int> _meshesTranslucent;
QVector<int> _meshesTranslucentTangents;
QVector<int> _meshesTranslucentTangentsSpecular;
QVector<int> _meshesTranslucentSpecular;
QVector<int> _meshesTranslucentSkinned;
QVector<int> _meshesTranslucentTangentsSkinned;
QVector<int> _meshesTranslucentTangentsSpecularSkinned;
QVector<int> _meshesTranslucentSpecularSkinned;
QVector<int> _meshesOpaque;
QVector<int> _meshesOpaqueTangents;
QVector<int> _meshesOpaqueTangentsSpecular;
QVector<int> _meshesOpaqueSpecular;
QVector<int> _meshesOpaqueSkinned;
QVector<int> _meshesOpaqueTangentsSkinned;
QVector<int> _meshesOpaqueTangentsSpecularSkinned;
QVector<int> _meshesOpaqueSpecularSkinned;
QVector<int> _meshesOpaqueLightmap;
QVector<int> _meshesOpaqueLightmapTangents;
QVector<int> _meshesOpaqueLightmapTangentsSpecular;
QVector<int> _meshesOpaqueLightmapSpecular;
// debug rendering support
void renderDebugMeshBoxes();
@ -490,6 +438,17 @@ private:
int getRaw() { return *reinterpret_cast<int*>(this); }
RenderKey(
bool translucent, bool hasLightmap,
bool hasTangents, bool hasSpecular, bool isSkinned) :
RenderKey( (translucent ? IS_TRANSLUCENT : 0)
| (hasLightmap ? HAS_LIGHTMAP : 0)
| (hasTangents ? HAS_TANGENTS : 0)
| (hasSpecular ? HAS_SPECULAR : 0)
| (isSkinned ? IS_SKINNED : 0)
) {}
RenderKey(RenderArgs::RenderMode mode,
bool translucent, float alphaThreshold, bool hasLightmap,
bool hasTangents, bool hasSpecular, bool isSkinned) :
@ -527,6 +486,19 @@ private:
};
static RenderPipelineLib _renderPipelineLib;
class RenderBucket {
public:
QVector<int> _meshes;
QMap<QString, int> _unsortedMeshes;
};
typedef std::unordered_map<int, RenderBucket> BaseRenderBucketMap;
class RenderBucketMap : public BaseRenderBucketMap {
public:
typedef RenderKey Key;
};
RenderBucketMap _renderBuckets;
bool _renderCollisionHull;
};