mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 18:41:10 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into orange
This commit is contained in:
commit
11879f6142
10 changed files with 182 additions and 380 deletions
|
@ -1748,7 +1748,10 @@ void Application::setActiveFaceTracker() {
|
||||||
DependencyManager::get<Faceshift>()->setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift));
|
DependencyManager::get<Faceshift>()->setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift));
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_DDE
|
#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
|
#endif
|
||||||
#ifdef HAVE_VISAGE
|
#ifdef HAVE_VISAGE
|
||||||
DependencyManager::get<Visage>()->updateEnabled();
|
DependencyManager::get<Visage>()->updateEnabled();
|
||||||
|
|
|
@ -210,7 +210,6 @@ public:
|
||||||
bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; }
|
bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; }
|
||||||
|
|
||||||
FaceTracker* getActiveFaceTracker();
|
FaceTracker* getActiveFaceTracker();
|
||||||
void setActiveFaceTracker();
|
|
||||||
|
|
||||||
QSystemTrayIcon* getTrayIcon() { return _trayIcon; }
|
QSystemTrayIcon* getTrayIcon() { return _trayIcon; }
|
||||||
ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; }
|
ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; }
|
||||||
|
@ -385,6 +384,8 @@ public slots:
|
||||||
void setVSyncEnabled();
|
void setVSyncEnabled();
|
||||||
|
|
||||||
void resetSensors();
|
void resetSensors();
|
||||||
|
void setActiveFaceTracker();
|
||||||
|
|
||||||
void aboutApp();
|
void aboutApp();
|
||||||
void showEditEntitiesHelp();
|
void showEditEntitiesHelp();
|
||||||
|
|
||||||
|
|
|
@ -362,30 +362,32 @@ Menu::Menu() {
|
||||||
|
|
||||||
QAction* noFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::NoFaceTracking,
|
QAction* noFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::NoFaceTracking,
|
||||||
0, true,
|
0, true,
|
||||||
this, SLOT(setActiveFaceTracker()));
|
qApp, SLOT(setActiveFaceTracker()));
|
||||||
faceTrackerGroup->addAction(noFaceTracker);
|
faceTrackerGroup->addAction(noFaceTracker);
|
||||||
|
|
||||||
#ifdef HAVE_FACESHIFT
|
#ifdef HAVE_FACESHIFT
|
||||||
QAction* faceshiftFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::Faceshift,
|
QAction* faceshiftFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::Faceshift,
|
||||||
0, false,
|
0, false,
|
||||||
this, SLOT(setActiveFaceTracker()));
|
qApp, SLOT(setActiveFaceTracker()));
|
||||||
faceTrackerGroup->addAction(faceshiftFaceTracker);
|
faceTrackerGroup->addAction(faceshiftFaceTracker);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_DDE
|
#ifdef HAVE_DDE
|
||||||
QAction* ddeFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::DDEFaceRegression,
|
QAction* ddeFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::DDEFaceRegression,
|
||||||
0, false,
|
0, false,
|
||||||
this, SLOT(setActiveFaceTracker()));
|
qApp, SLOT(setActiveFaceTracker()));
|
||||||
faceTrackerGroup->addAction(ddeFaceTracker);
|
faceTrackerGroup->addAction(ddeFaceTracker);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_VISAGE
|
#ifdef HAVE_VISAGE
|
||||||
QAction* visageFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::Visage,
|
QAction* visageFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::Visage,
|
||||||
0, false,
|
0, false,
|
||||||
this, SLOT(setActiveFaceTracker()));
|
qApp, SLOT(setActiveFaceTracker()));
|
||||||
faceTrackerGroup->addAction(visageFaceTracker);
|
faceTrackerGroup->addAction(visageFaceTracker);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef HAVE_DDE
|
#ifdef HAVE_DDE
|
||||||
faceTrackingMenu->addSeparator();
|
faceTrackingMenu->addSeparator();
|
||||||
|
QAction* ddeFiltering = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::DDEFiltering, 0, true);
|
||||||
|
ddeFiltering->setVisible(false);
|
||||||
QAction* ddeFaceTrackerReset = addActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::ResetDDETracking,
|
QAction* ddeFaceTrackerReset = addActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::ResetDDETracking,
|
||||||
Qt::CTRL | Qt::Key_Apostrophe,
|
Qt::CTRL | Qt::Key_Apostrophe,
|
||||||
DependencyManager::get<DdeFaceTracker>().data(), SLOT(resetTracking()));
|
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.";
|
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();
|
|
||||||
}
|
|
||||||
|
|
|
@ -68,7 +68,6 @@ public slots:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void setVisibility();
|
void setVisibility();
|
||||||
void setActiveFaceTracker();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Menu* _instance;
|
static Menu* _instance;
|
||||||
|
@ -137,6 +136,7 @@ namespace MenuOption {
|
||||||
const QString CopyAddress = "Copy Address to Clipboard";
|
const QString CopyAddress = "Copy Address to Clipboard";
|
||||||
const QString CopyPath = "Copy Path to Clipboard";
|
const QString CopyPath = "Copy Path to Clipboard";
|
||||||
const QString DDEFaceRegression = "DDE Face Regression";
|
const QString DDEFaceRegression = "DDE Face Regression";
|
||||||
|
const QString DDEFiltering = "DDE Filtering";
|
||||||
const QString DecreaseAvatarSize = "Decrease Avatar Size";
|
const QString DecreaseAvatarSize = "Decrease Avatar Size";
|
||||||
const QString DeleteBookmark = "Delete Bookmark...";
|
const QString DeleteBookmark = "Delete Bookmark...";
|
||||||
const QString DisableActivityLogger = "Disable Activity Logger";
|
const QString DisableActivityLogger = "Disable Activity Logger";
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
|
|
||||||
|
#include <GLMHelpers.h>
|
||||||
|
|
||||||
#include "DdeFaceTracker.h"
|
#include "DdeFaceTracker.h"
|
||||||
#include "FaceshiftConstants.h"
|
#include "FaceshiftConstants.h"
|
||||||
#include "InterfaceLogging.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_SERVER_PORT = 64204;
|
||||||
static const quint16 DDE_CONTROL_PORT = 64205;
|
static const quint16 DDE_CONTROL_PORT = 64205;
|
||||||
#if defined(Q_OS_WIN)
|
#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)
|
#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
|
#endif
|
||||||
static const QStringList DDE_ARGUMENTS = QStringList()
|
static const QStringList DDE_ARGUMENTS = QStringList()
|
||||||
<< "--udp=" + DDE_SERVER_ADDR.toString() + ":" + QString::number(DDE_SERVER_PORT)
|
<< "--udp=" + DDE_SERVER_ADDR.toString() + ":" + QString::number(DDE_SERVER_PORT)
|
||||||
|
@ -132,6 +134,8 @@ struct Packet {
|
||||||
char name[MAX_NAME_SIZE + 1];
|
char name[MAX_NAME_SIZE + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const float STARTING_DDE_MESSAGE_TIME = 0.033f;
|
||||||
|
|
||||||
DdeFaceTracker::DdeFaceTracker() :
|
DdeFaceTracker::DdeFaceTracker() :
|
||||||
DdeFaceTracker(QHostAddress::Any, DDE_SERVER_PORT, DDE_CONTROL_PORT)
|
DdeFaceTracker(QHostAddress::Any, DDE_SERVER_PORT, DDE_CONTROL_PORT)
|
||||||
{
|
{
|
||||||
|
@ -157,11 +161,16 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui
|
||||||
_mouthSmileLeftIndex(28),
|
_mouthSmileLeftIndex(28),
|
||||||
_mouthSmileRightIndex(29),
|
_mouthSmileRightIndex(29),
|
||||||
_jawOpenIndex(21),
|
_jawOpenIndex(21),
|
||||||
_previousTranslation(glm::vec3()),
|
_lastMessageReceived(0),
|
||||||
_previousRotation(glm::quat())
|
_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);
|
_coefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
||||||
_previousCoefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
|
||||||
|
|
||||||
_blendshapeCoefficients.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) {
|
void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
||||||
if(buffer.size() > MIN_PACKET_SIZE) {
|
if(buffer.size() > MIN_PACKET_SIZE) {
|
||||||
|
bool isFiltering = Menu::getInstance()->isOptionChecked(MenuOption::DDEFiltering);
|
||||||
|
|
||||||
Packet packet;
|
Packet packet;
|
||||||
int bytesToCopy = glm::min((int)sizeof(packet), buffer.size());
|
int bytesToCopy = glm::min((int)sizeof(packet), buffer.size());
|
||||||
memset(&packet.name, '\n', MAX_NAME_SIZE + 1);
|
memset(&packet.name, '\n', MAX_NAME_SIZE + 1);
|
||||||
|
@ -292,13 +303,36 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
||||||
translation -= _referenceTranslation;
|
translation -= _referenceTranslation;
|
||||||
translation /= LEAN_DAMPING_FACTOR;
|
translation /= LEAN_DAMPING_FACTOR;
|
||||||
translation.x *= -1;
|
translation.x *= -1;
|
||||||
_headTranslation = (translation + _previousTranslation) / 2.0f;
|
if (isFiltering) {
|
||||||
_previousTranslation = translation;
|
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
|
// Compute relative rotation
|
||||||
rotation = glm::inverse(_referenceRotation) * rotation;
|
rotation = glm::inverse(_referenceRotation) * rotation;
|
||||||
_headRotation = (rotation + _previousRotation) / 2.0f;
|
if (isFiltering) {
|
||||||
_previousRotation = rotation;
|
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
|
// Translate DDE coefficients to Faceshift compatible coefficients
|
||||||
for (int i = 0; i < NUM_EXPRESSIONS; i += 1) {
|
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
|
// Use EyeBlink values to control both EyeBlink and EyeOpen
|
||||||
static const float RELAXED_EYE_VALUE = 0.1f;
|
static const float RELAXED_EYE_VALUE = 0.1f;
|
||||||
float leftEye = (_coefficients[_leftBlinkIndex] + _previousCoefficients[_leftBlinkIndex]) / 2.0f;
|
float leftEye = _coefficients[_leftBlinkIndex];
|
||||||
float rightEye = (_coefficients[_rightBlinkIndex] + _previousCoefficients[_rightBlinkIndex]) / 2.0f;
|
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) {
|
if (leftEye > RELAXED_EYE_VALUE) {
|
||||||
_coefficients[_leftBlinkIndex] = leftEye - RELAXED_EYE_VALUE;
|
_coefficients[_leftBlinkIndex] = leftEye - RELAXED_EYE_VALUE;
|
||||||
_coefficients[_leftEyeOpenIndex] = 0.0f;
|
_coefficients[_leftEyeOpenIndex] = 0.0f;
|
||||||
|
@ -343,10 +392,18 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
||||||
// Scale all coefficients
|
// Scale all coefficients
|
||||||
for (int i = 0; i < NUM_EXPRESSIONS; i += 1) {
|
for (int i = 0; i < NUM_EXPRESSIONS; i += 1) {
|
||||||
_blendshapeCoefficients[i]
|
_blendshapeCoefficients[i]
|
||||||
= glm::clamp(DDE_COEFFICIENT_SCALES[i] * (_coefficients[i] + _previousCoefficients[i]) / 2.0f, 0.0f, 1.0f);
|
= glm::clamp(DDE_COEFFICIENT_SCALES[i] * _coefficients[i], 0.0f, 1.0f);
|
||||||
_previousCoefficients[i] = _coefficients[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 {
|
} else {
|
||||||
qCDebug(interfaceapp) << "[Error] DDE Face Tracker Decode Error";
|
qCDebug(interfaceapp) << "[Error] DDE Face Tracker Decode Error";
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,10 +101,14 @@ private:
|
||||||
|
|
||||||
QVector<float> _coefficients;
|
QVector<float> _coefficients;
|
||||||
|
|
||||||
// Previous values for simple smoothing
|
quint64 _lastMessageReceived;
|
||||||
glm::vec3 _previousTranslation;
|
float _averageMessageTime;
|
||||||
glm::quat _previousRotation;
|
glm::vec3 _lastHeadTranslation;
|
||||||
QVector<float> _previousCoefficients;
|
glm::vec3 _filteredHeadTranslation;
|
||||||
|
float _lastLeftEyeBlink;
|
||||||
|
float _filteredLeftEyeBlink;
|
||||||
|
float _lastRightEyeBlink;
|
||||||
|
float _filteredRightEyeBlink;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_DdeFaceTracker_h
|
#endif // hifi_DdeFaceTracker_h
|
|
@ -1705,7 +1705,12 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
||||||
material._material->setDiffuse(material.diffuse);
|
material._material->setDiffuse(material.diffuse);
|
||||||
material._material->setSpecular(material.specular);
|
material._material->setSpecular(material.specular);
|
||||||
material._material->setShininess(material.shininess);
|
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);
|
materials.insert(material.id, material);
|
||||||
|
|
||||||
|
|
|
@ -12,4 +12,16 @@ add_dependency_external_projects(glm)
|
||||||
find_package(GLM REQUIRED)
|
find_package(GLM REQUIRED)
|
||||||
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
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)
|
link_hifi_libraries(animation fbx shared gpu)
|
|
@ -244,13 +244,6 @@ void Model::initJointTransforms() {
|
||||||
|
|
||||||
void Model::init() {
|
void Model::init() {
|
||||||
if (_renderPipelineLib.empty()) {
|
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
|
// Vertex shaders
|
||||||
auto modelVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_vert)));
|
auto modelVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_vert)));
|
||||||
auto modelNormalMapVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_normal_map_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),
|
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);
|
||||||
|
|
||||||
|
_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(
|
_renderPipelineLib.addRenderPipeline(
|
||||||
RenderKey(RenderKey::HAS_LIGHTMAP),
|
RenderKey(RenderKey::HAS_LIGHTMAP),
|
||||||
modelLightmapVertex, modelLightmapPixel);
|
modelLightmapVertex, modelLightmapPixel);
|
||||||
|
@ -310,6 +317,7 @@ void Model::init() {
|
||||||
RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
|
RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
|
||||||
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
|
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
|
||||||
|
|
||||||
|
|
||||||
_renderPipelineLib.addRenderPipeline(
|
_renderPipelineLib.addRenderPipeline(
|
||||||
RenderKey(RenderKey::IS_SKINNED),
|
RenderKey(RenderKey::IS_SKINNED),
|
||||||
skinModelVertex, modelPixel);
|
skinModelVertex, modelPixel);
|
||||||
|
@ -326,15 +334,29 @@ void Model::init() {
|
||||||
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
|
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
|
||||||
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
|
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||||
|
|
||||||
|
|
||||||
_renderPipelineLib.addRenderPipeline(
|
_renderPipelineLib.addRenderPipeline(
|
||||||
RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_TRANSLUCENT),
|
RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_TRANSLUCENT),
|
||||||
skinModelVertex, modelTranslucentPixel);
|
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(
|
_renderPipelineLib.addRenderPipeline(
|
||||||
RenderKey(RenderKey::IS_DEPTH_ONLY | RenderKey::IS_SHADOW),
|
RenderKey(RenderKey::IS_DEPTH_ONLY | RenderKey::IS_SHADOW),
|
||||||
modelShadowVertex, modelShadowPixel);
|
modelShadowVertex, modelShadowPixel);
|
||||||
|
|
||||||
|
|
||||||
_renderPipelineLib.addRenderPipeline(
|
_renderPipelineLib.addRenderPipeline(
|
||||||
RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_DEPTH_ONLY | RenderKey::IS_SHADOW),
|
RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_DEPTH_ONLY | RenderKey::IS_SHADOW),
|
||||||
skinModelShadowVertex, modelShadowPixel);
|
skinModelShadowVertex, modelShadowPixel);
|
||||||
|
@ -1935,55 +1957,7 @@ bool Model::renderInScene(float alpha, RenderArgs* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::segregateMeshGroups() {
|
void Model::segregateMeshGroups() {
|
||||||
_meshesTranslucentTangents.clear();
|
_renderBuckets.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();
|
|
||||||
|
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
|
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
|
||||||
|
@ -2017,201 +1991,19 @@ void Model::segregateMeshGroups() {
|
||||||
qCDebug(renderutils) << "materialID:" << materialID << "parts:" << mesh.parts.size();
|
qCDebug(renderutils) << "materialID:" << materialID << "parts:" << mesh.parts.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasLightmap) {
|
RenderKey key(translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||||
if (translucentMesh && !hasTangents && !hasSpecular && !isSkinned) {
|
|
||||||
|
|
||||||
_unsortedMeshesTranslucent.insertMulti(materialID, i);
|
// reuse or create the bucket corresponding to that key and insert the mesh as unsorted
|
||||||
|
_renderBuckets[key.getRaw()]._unsortedMeshes.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???";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(int i, _unsortedMeshesTranslucent) {
|
for(auto& b : _renderBuckets) {
|
||||||
_meshesTranslucent.append(i);
|
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;
|
_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
|
// depending on which parameters we were called with, pick the correct mesh group to render
|
||||||
QVector<int>* whichList = NULL;
|
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) {
|
RenderKey key(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;
|
|
||||||
|
|
||||||
} else if (!translucent && hasLightmap && !hasTangents && !hasSpecular && !isSkinned) {
|
auto bucket = _renderBuckets.find(key.getRaw());
|
||||||
whichList = &_meshesOpaqueLightmap;
|
if (bucket != _renderBuckets.end()) {
|
||||||
} else if (!translucent && hasLightmap && hasTangents && !hasSpecular && !isSkinned) {
|
whichList = &(*bucket).second._meshes;
|
||||||
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???";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return whichList;
|
return whichList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2277,6 +2031,7 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
||||||
auto pipeline = _renderPipelineLib.find(key.getRaw());
|
auto pipeline = _renderPipelineLib.find(key.getRaw());
|
||||||
if (pipeline == _renderPipelineLib.end()) {
|
if (pipeline == _renderPipelineLib.end()) {
|
||||||
qDebug() << "No good, couldn't find a pipeline from the key ?" << key.getRaw();
|
qDebug() << "No good, couldn't find a pipeline from the key ?" << key.getRaw();
|
||||||
|
locations = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2303,7 +2058,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
|
||||||
int meshPartsRendered = 0;
|
int meshPartsRendered = 0;
|
||||||
|
|
||||||
bool pickProgramsNeeded = true;
|
bool pickProgramsNeeded = true;
|
||||||
Locations* locations;
|
Locations* locations = nullptr;
|
||||||
|
|
||||||
foreach(Model* model, _modelsInScene) {
|
foreach(Model* model, _modelsInScene) {
|
||||||
QVector<int>* whichList = model->pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
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__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
int meshPartsRendered = 0;
|
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) {
|
if (!whichList) {
|
||||||
qCDebug(renderutils) << "unexpected!!! we don't know which list of meshes to render...";
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
QVector<int>& list = *whichList;
|
QVector<int>& list = *whichList;
|
||||||
|
|
||||||
// If this list has nothing to render, then don't bother proceeding. This saves us on binding to programs
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Locations* locations;
|
Locations* locations = nullptr;
|
||||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned,
|
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned,
|
||||||
args, locations);
|
args, locations);
|
||||||
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
|
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
|
||||||
|
|
|
@ -350,58 +350,6 @@ private:
|
||||||
|
|
||||||
bool _meshGroupsKnown;
|
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
|
// debug rendering support
|
||||||
void renderDebugMeshBoxes();
|
void renderDebugMeshBoxes();
|
||||||
|
@ -490,6 +438,17 @@ private:
|
||||||
|
|
||||||
int getRaw() { return *reinterpret_cast<int*>(this); }
|
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,
|
RenderKey(RenderArgs::RenderMode mode,
|
||||||
bool translucent, float alphaThreshold, bool hasLightmap,
|
bool translucent, float alphaThreshold, bool hasLightmap,
|
||||||
bool hasTangents, bool hasSpecular, bool isSkinned) :
|
bool hasTangents, bool hasSpecular, bool isSkinned) :
|
||||||
|
@ -527,6 +486,19 @@ private:
|
||||||
};
|
};
|
||||||
static RenderPipelineLib _renderPipelineLib;
|
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;
|
bool _renderCollisionHull;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue